2364. Count Number of Bad Pairs - Explanation

Problem Link



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

  1. Initialize a counter for bad pairs.
  2. Use two nested loops: the outer loop picks index i, the inner loop picks index j where j > i.
  3. For each pair, check if j - i != nums[j] - nums[i].
  4. If the condition is true, increment the bad pair counter.
  5. Return the total count.
class Solution:
    def countBadPairs(self, nums: List[int]) -> int:
        n, res = len(nums), 0
        for i in range(n - 1):
            for j in range(i + 1, n):
                if j - i != nums[j] - nums[i]:
                    res += 1
        return res

Time & Space Complexity

  • Time complexity: O(n2)O(n ^ 2)
  • Space complexity: O(1)O(1)

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

  1. Use a hash map to track the frequency of each nums[i] - i value.
  2. Keep a running total of pairs seen so far (which equals i at index i).
  3. For each index, add the count of previously seen elements with the same transformed value to the good pairs count.
  4. Update the hash map with the current transformed value.
  5. Return total pairs minus good pairs.
class Solution:
    def countBadPairs(self, nums: List[int]) -> int:
        good_pairs = 0
        total_pairs = 0
        count = defaultdict(int)

        for i in range(len(nums)):
            total_pairs += i
            good_pairs += count[nums[i] - i]
            count[nums[i] - i] += 1

        return total_pairs - good_pairs

Time & Space Complexity

  • Time complexity: O(n)O(n)
  • Space complexity: O(n)O(n)

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.