Count Number of Bad Pairs

Updated on 09 May, 2025
Count Number of Bad Pairs header image

Problem Statement

Given a 0-indexed integer array nums, a pair of indices (i, j) is defined as a "bad pair" if i < j and j - i is not equal to nums[j] - nums[i]. The goal is to determine the total number of bad pairs present in the array. This problem essentially asks us to count the occurrences where the difference in index values does not match the difference in their respective values from the array.

Examples

Example 1

Input:

nums = [4,1,3,3]

Output:

5

Explanation:

The pair (0, 1) is a bad pair since 1 - 0 != 1 - 4.
The pair (0, 2) is a bad pair since 2 - 0 != 3 - 4, 2 != -1.
The pair (0, 3) is a bad pair since 3 - 0 != 3 - 4, 3 != -1.
The pair (1, 2) is a bad pair since 2 - 1 != 3 - 1, 1 != 2.
The pair (2, 3) is a bad pair since 3 - 2 != 3 - 3, 1 != 0.
There are a total of 5 bad pairs, so we return 5.

Example 2

Input:

nums = [1,2,3,4,5]

Output:

0

Explanation:

There are no bad pairs.

Constraints

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 109

Approach and Intuition

To solve this problem, understanding it through examples helps in breaking down what a "bad pair" actually signifies, let's examine a systematic approach:

  1. Touch Base with Constraints: First, note the constraints:

    • Array length can be up to 100,000.
    • Element values can be as large as 1 billion.
    • These constraints hint that a solution with a quadratic complexity (e.g., checking each pair through nested loops) will not be efficient enough.
  2. Understanding the Condition For Bad Pair:

    • For each pair of indices (i, j) to not be bad, the equation j - i = nums[j] - nums[i] must hold.
    • Given another way, if we rearrange, j - nums[j] must equal i - nums[i].
  3. Hash Map to Store Occurrences:

    • Using a hashmap to track how often each value of j - nums[j] (let's call this 'key') appears can be instrumental. Once we have this, the total number of pairs for any i, j that do not have the same 'key' are potentionally bad pairs.
  4. Counting Bad Pairs:

    • Calculate the total number of pairs (i, j) which are i < j from 0 to n-1. This forms a triangular number which is n(n-1)/2.
    • Subtract the number of good pairs (pairs which match the j - nums[j] == i - nums[i] condition) from the total pairs computed above.
  5. Use Previous Examples for Practical Understanding:

    • From the provided examples, the thought process and computations are elaborated for clarity on bad and good pairs determination:
      • Example 1: nums = [4,1,3,3] gives 5 bad pairs, as none of the pairs satisfy the condition of matching j - nums[j] with i - nums[i].
      • Example 2: nums = [1,2,3,4,5], here all increments are uniform hence no bad pairs.

This approach provides us a methodical way to identify and count pairs that do not meet a specific relational condition between elements and their indices, while ensuring efficiency in computations even for large inputs. This is essential given the constraints of the problem.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    long long countIncorrectPairs(vector<int>& elements) {
        long long badPairCount = 0;
        unordered_map<int, int> diffMap;

        for (int index = 0; index < elements.size(); index++) {
            int difference = index - elements[index];
            
            int countOfGoodPairs = diffMap[difference];
            
            badPairCount += index - countOfGoodPairs;
            
            diffMap[difference] = countOfGoodPairs + 1;
        }

        return badPairCount;
    }
};

The given C++ program aims to calculate the number of "bad pairs" in a vector of integers labelled as elements. A bad pair is defined as a pair of indices (i, j) where i < j and i - elements[i] does not equal j - elements[j].

  • The method countIncorrectPairs is defined to compute the number of bad pairs.
  • Inside this method, a variable badPairCount is used to maintain the count of bad pairs found during the execution.
  • An unordered_map named diffMap stores the difference index - elements[index] for each index, alongside the count of how many times this difference has occurred.
  • The program efficiently manages the computation by iterating through each element of the array:
    • For each index, it calculates the difference, index - elements[index].
    • Using this difference, the program checks how many times this difference has previously appeared (countOfGoodPairs from diffMap).
    • The number of bad pairs is then incremented by the total number of previous indices minus the number of times the current computed difference has occurred. This calculation ensures that the reverse scenarios are accounted for.
    • The difference count for this index is updated in diffMap.

This method efficiently calculates the count of bad pairs by leveraging the difference between the indices and their respective values, ensuring that the need for comparing every possible pair (which is computationally expensive) is avoided. This results in a more optimized solution in terms of both time and space complexities.

java
class Solution {

    public long calculateBadPairs(int[] values) {
        long badPairCount = 0;
        Map<Integer, Integer> diffMap = new HashMap<>();

        for (int index = 0; index < values.length; index++) {
            int difference = index - values[index];
            int existCount = diffMap.getOrDefault(difference, 0);

            badPairCount += index - existCount;
            diffMap.put(difference, existCount + 1);
        }

        return badPairCount;
    }
}

The Java solution provided calculates the number of bad pairs in an array of integers. A pair (i, j) is defined as bad if (i < j) yet j - values[j] != i - values[i]. The problem is approached by using a HashMap to keep track of frequency of the differences between index positions and their corresponding values.

Here is a breakdown of how the solution is implemented:

  • Initialize badPairCount to keep a running total of bad pairs.
  • Create a diffMap HashMap to store frequencies of each difference between indices and values.
  • Loop through the array using an index. For each element:
    • Calculate difference as (index - values[index]).
    • Retrieve the count of this difference from diffMap using getOrDefault(), which fetches the count if it exists, or returns 0 if it doesn't.
    • Increment the badPairCount by (index - existCount). This represents the number of new bad pairs found at the current index.
    • Update diffMap by increasing the count of the current difference.
  • Return badPairCount.

This approach ensures optimal performance by avoiding the brute force method of comparing each pair, leveraging the properties of differences to find and count bad pairs efficiently.

python
class Solution:
    def countNonGoodPairs(self, elements: List[int]) -> int:
        non_good_pairs = 0
        diff_tracker = {}

        for index in range(len(elements)):
            current_diff = index - elements[index]

            # Existing counts of good pairs with same difference
            current_good_pairs = diff_tracker.get(current_diff, 0)

            # Calculate non-good pairs by subtracting number of good pairs from possible pairs
            non_good_pairs += index - current_good_pairs

            # Update our tracker for this current difference
            diff_tracker[current_diff] = current_good_pairs + 1

        return non_good_pairs

The Python3 code provided effectively counts the number of non-good pairs in an array where a pair (i, j) is considered bad if i < j and i - j ≠ elements[i] - elements[j]. It uses a dictionary to track the frequency of differences (index - elements[index]), which helps identify the good pairs.

Here's a breakdown of the solution logic:

  • Initialize a variable non_good_pairs to zero to store the count of non-good pairs.
  • Use a dictionary diff_tracker to keep track of the differences and their counts.
  • Iterate through the array elements using the index.
  • Compute the difference between the current index and the value at that index.
  • Fetch the current count of good pairs that have the same calculated difference from diff_tracker.
  • Calculate non-good pairs by subtracting the good pairs from the total possible pairs up to the current index.
  • Update the count of the current difference in the tracker.
  • Finally, the function returns the total non_good_pairs.

This approach efficiently utilizes a dictionary to avoid the direct computation of each pair, thus optimizing the solution by minimizing redundant operations and making use of past computations.

Comments

No comments yet.