2364. Count Number of Bad Pairs - Explanation
Prerequisites
Before attempting this problem, you should be comfortable with:
- Hash Maps - Used to efficiently track and count elements with the same transformed value
- Algebraic Manipulation - Rearranging the bad pair condition to group elements efficiently
- Counting Pairs - Understanding how to count total pairs and use complementary counting (total pairs minus good pairs)
1. Brute Force
Intuition
A bad pair is defined as i < j where j - i != nums[j] - nums[i]. We can check every possible pair of indices and count how many satisfy this condition.
Algorithm
- Initialize a counter for bad pairs.
- Use two nested loops: the outer loop picks index
i, the inner loop picks indexjwherej > i. - For each pair, check if
j - i != nums[j] - nums[i]. - If the condition is true, increment the bad pair counter.
- Return the total count.
Time & Space Complexity
- Time complexity:
- Space complexity:
2. Hash Map
Intuition
Rearranging the bad pair condition j - i != nums[j] - nums[i] gives us nums[j] - j != nums[i] - i. This means a pair is "good" when both elements have the same value of nums[k] - k. Instead of counting bad pairs directly, we count the total pairs and subtract the good pairs. Elements with the same transformed value form good pairs among themselves.
Algorithm
- Use a hash map to track the frequency of each
nums[i] - ivalue. - Keep a running total of pairs seen so far (which equals
iat indexi). - For each index, add the count of previously seen elements with the same transformed value to the good pairs count.
- Update the hash map with the current transformed value.
- Return total pairs minus good pairs.
Time & Space Complexity
- Time complexity:
- Space complexity:
Common Pitfalls
Counting Bad Pairs Directly
Trying to count bad pairs directly with a hash map is error-prone. The cleaner approach is to count good pairs (where nums[i] - i == nums[j] - j) and subtract from total pairs.
Integer Overflow with Large Arrays
With n up to 10^5, the total number of pairs is n*(n-1)/2 which can exceed 32-bit integer limits. Use long or 64-bit integers for the result.
// Wrong: overflow for large n
int res = 0;
// Correct: use long
long res = 0;Forgetting the Algebraic Transformation
The key insight is rewriting j - i != nums[j] - nums[i] as nums[i] - i != nums[j] - j. Without this transformation, you cannot efficiently group elements using a hash map.