Cracking LeetCode 2784: Is This Array "Good"? Let's Find Out!
Hey everyone! Vansh2710 here, your friendly neighborhood competitive programmer and technical writing enthusiast! Today, we're diving into a fun little LeetCode problem that's perfect for beginners to sharpen their logical thinking: 2784. Check if Array is Good.
Don't let the "permutation" jargon scare you. We'll break it down step by step and discover an elegant solution together. Ready to level up your LeetCode game? Let's go!
🚀 Problem Explanation: What Makes an Array "Good"?
Imagine you have a special kind of array called base[n]. This base[n] array always looks like this:
[1, 2, ..., n - 1, n, n]
In plain English, it's an array of length n + 1 that contains:
- All numbers from
1up ton - 1appear exactly once. - The number
nappears exactly twice.
For example:
- If
n = 1, thenbase[1] = [1, 1]. (Length 1+1=2) - If
n = 3, thenbase[3] = [1, 2, 3, 3]. (Length 3+1=4) - If
n = 5, thenbase[5] = [1, 2, 3, 4, 5, 5]. (Length 5+1=6)
The problem asks us to determine if a given array nums is a permutation of one of these base[n] arrays. "Permutation" just means it contains the same numbers, just possibly in a different order.
Let's look at the examples:
-
nums = [2, 1, 3]- The largest number is
3. So, if this were abase[n]array,nmust be3. -
base[3]should be[1, 2, 3, 3], which has 4 elements. - But
numshas only 3 elements. So, it cannot bebase[3]. Output:false.
- The largest number is
-
nums = [1, 3, 3, 2]- The largest number is
3. So,nmust be3. -
base[3]is[1, 2, 3, 3]. -
numsalso has 4 elements, just likebase[3]. - Can we rearrange
[1, 3, 3, 2]to get[1, 2, 3, 3]? Yes! They contain the exact same numbers with the same counts. Output:true.
- The largest number is
-
nums = [3, 4, 4, 1, 2, 1]- Largest number is
4. So,nmust be4. -
base[4]should be[1, 2, 3, 4, 4], which has 5 elements. - But
numshas 6 elements. It's too long! Output:false.
- Largest number is
See? It's all about checking the elements, their counts, and the array's length!
💡 Intuition: The "Aha!" Moment
When you're trying to figure out if an array is a "permutation" of another specific array structure, the first thing that often comes to mind is sorting. If two arrays are permutations of each other, they will be identical once sorted.
So, if nums is a "good" array, after sorting it, it should exactly match [1, 2, ..., n - 1, n, n].
But what is n? The problem examples give us a HUGE hint: n is always the maximum value present in the nums array. If the nums array is supposed to be base[n], then n is the highest number appearing twice, and n-1 is the next highest. So, n must be the largest element.
Once we figure out n (by finding the maximum value in nums), we can determine two key properties that nums must satisfy:
- Length Check:
numsmust haven + 1elements. - Content Check: After sorting,
numsmust look exactly like[1, 2, ..., n - 1, n, n].
If nums passes both these checks, it's a "good" array!
🧠 Approach: Step-by-Step Logic
Let's put our intuition into a concrete plan:
-
Determine the Candidate
n:- Find the maximum element in the input array
nums. Let's call thismax_val. Thismax_valis our candidatenfrombase[n].
- Find the maximum element in the input array
-
Initial Length Check:
- The
base[n]array always has a length ofn + 1. - Check if the
nums.size()(the actual number of elements innums) is equal tomax_val + 1. - If
nums.size()is not equal tomax_val + 1, thennumscannot be a permutation ofbase[max_val]. Immediately returnfalse.
- The
-
Sort the Array:
- Sort the
numsarray in non-decreasing order. This makes it easy to check the pattern[1, 2, ..., n - 1, n, n].
- Sort the
-
Verify Elements in Order:
- After sorting, we expect the elements to be
1, 2, ..., max_val - 1, max_val, max_val. - Loop from
i = 0up tomax_val - 2(which means checking elementsnums[0]throughnums[max_val - 2]). - In this loop, for each
i, check ifnums[i]is equal toi + 1. If it's not, it means we don't have the sequence1, 2, 3, .... Returnfalse. - Special Case: What if
max_valis 1? Ifmax_val = 1, thenbase[1] = [1, 1]. The loopifrom0tomax_val - 2(i.e.,0to-1) won't run, which is correct. We only need to check the two1s.
- After sorting, we expect the elements to be
-
Verify the Duplicate
n(ormax_val):- After the loop, we need to check the last two elements. These should both be
max_val. - Since
nums.size()ismax_val + 1, the elements are at indices0tomax_val. - So, we need to check if
nums[max_val - 1]is equal tomax_valANDnums[max_val]is equal tomax_val. - If both these conditions are true, then
numshas the required duplicatemax_val. If not, returnfalse.
- After the loop, we need to check the last two elements. These should both be
-
All Checks Passed:
- If we've made it this far, it means
numshas the correct length, and its sorted elements match thebase[max_val]pattern. Returntrue.
- If we've made it this far, it means
This approach covers all the conditions systematically and efficiently!
💻 Code: Bringing the Logic to Life
Here's the C++ implementation of our approach:
#include <vector>
#include <algorithm> // Required for std::sort and std::max_element
class Solution {
public:
bool isGood(std::vector<int>& nums) {
int current_size = nums.size();
// Step 1: Determine the candidate 'n' (max_val)
// If the array is empty, it can't be good (constraints say nums.length >= 1)
// If only one element, max_element will still work.
int max_val = 0;
for (int x : nums) {
if (x > max_val) {
max_val = x;
}
}
// An alternative using std::max_element (requires <algorithm>):
// int max_val = *std::max_element(nums.begin(), nums.end());
// Step 2: Initial Length Check
// base[max_val] has length max_val + 1
if (current_size != max_val + 1) {
return false;
}
// Step 3: Sort the Array
std::sort(nums.begin(), nums.end());
// Step 4: Verify Elements 1 to (max_val - 1)
// Loop up to max_val - 1 (exclusive, so indices 0 to max_val - 2)
// For example, if max_val = 3, we check nums[0] == 1, nums[1] == 2.
for (int i = 0; i < max_val - 1; ++i) {
if (nums[i] != i + 1) {
return false;
}
}
// Step 5: Verify the Duplicate 'n' (max_val)
// The last two elements should both be max_val.
// These are at indices max_val - 1 and max_val (since current_size = max_val + 1)
if (nums[max_val - 1] != max_val || nums[max_val] != max_val) {
return false;
}
// Step 6: All Checks Passed
return true;
}
};
⏱️ Time & Space Complexity Analysis
Let's break down the efficiency of our solution:
-
Time Complexity:
- Finding
max_val: We iterate throughnumsonce. This takesO(N)time, whereNisnums.size(). - Sorting
nums: Usingstd::sorton astd::vectortakesO(N log N)time on average. - Checking elements after sorting: We loop through
numsat mostNtimes (specificallymax_valtimes, which is roughlyN). This takesO(N)time. - Overall: The dominant factor is the sorting step. Therefore, the total time complexity is
O(N log N).
- Finding
-
Space Complexity:
-
max_valandcurrent_sizevariables: These useO(1)constant space. -
std::sort: Forstd::vector,std::sorttypically uses an introspection sort algorithm, which hasO(log N)auxiliary space complexity for its recursive calls (orO(N)in worst-case for heapsort partition, but often considered in-place orO(log N)for the stack). For competitive programming contexts, it's often effectively treated asO(1)additional space if it sorts in-place. Let's consider it asO(1)(ignoring recursion stack space if small enough, orO(log N)more precisely for a typical implementation).
-
🎯 Key Takeaways
- Deconstruct the Problem: Break down complex definitions (like
base[n]) into simpler rules (length, distinct elements, duplicate element). - Leverage Hints: The example explanations often provide crucial clues, like how to determine
n(it's the max element!). - Sorting is Your Friend: For problems involving permutations or specific ordered structures, sorting is often the most straightforward way to normalize the input for easy validation.
- Edge Cases Matter: Always consider small
nvalues (liken=1) to ensure your logic holds. Our loop conditioni < max_val - 1correctly handlesmax_val = 1by not running the loop, which is perfect asbase[1]only needs[1, 1]checks. - Systematic Checks: Go through each requirement (length, distinct elements, duplicate elements) one by one. If any check fails, you can immediately return
false.
This problem is a fantastic warm-up to understanding how to translate descriptive array properties into a clear, implementable algorithm. Keep practicing!
Vansh2710
Published: 2026-05-14 22:44:58
Top comments (0)