You are given a 0-indexed integer array nums
. A pair of indices (i, j)
is a bad pair if i < j
and j - i != nums[j] - nums[i]
.
Return the total number of bad pairs in nums
.
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
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to finding bad pairs involves checking every possible pair of numbers to see if it fits the 'bad' criteria. We compare each number with every other number in the list to make sure we didn't miss any bad pairs.
Here's how the algorithm would work step-by-step:
def count_number_bad_pairs_brute_force(numbers):
bad_pair_count = 0
# Iterate through all possible pairs
for first_index in range(len(numbers)):
# Compare the current number with all subsequent numbers
for second_index in range(first_index + 1, len(numbers)):
# This is the core logic to detect if the pair is bad
if numbers[first_index] - numbers[second_index] != first_index - second_index:
bad_pair_count += 1
return bad_pair_count
The inefficient solution compares every pair, but that's slow. The optimal approach counts how many pairs are *not* bad, then subtracts that from the total number of possible pairs. This avoids unnecessary comparisons.
Here's how the algorithm would work step-by-step:
def count_bad_pairs(numbers):
list_length = len(numbers)
total_pairs = list_length * (list_length - 1) // 2
good_pairs = 0
previous_numbers = {}
for index, number in enumerate(numbers):
difference = number - index
#Check if we've seen a 'like' number before.
if difference in previous_numbers:
good_pairs += previous_numbers[difference]
# Update the count of the current difference.
if difference in previous_numbers:
previous_numbers[difference] += 1
else:
previous_numbers[difference] = 1
# Calculate the number of bad pairs.
return total_pairs - good_pairs
Case | How to Handle |
---|---|
Empty array or null input | Return 0 if the input array is null or empty, as there are no pairs. |
Array with only one element | Return 0, as a pair requires at least two elements. |
Array with all identical elements | The solution should correctly calculate the number of bad pairs when all elements are the same, which will be n * (n - 1) / 2. |
Array with a large number of elements (performance) | Use an efficient algorithm (e.g., using a HashMap or frequency counting) to avoid O(n^2) time complexity for large inputs. |
Array contains very large numbers (potential overflow during calculations) | Use appropriate data types (e.g., long) to prevent integer overflow when calculating differences or performing other arithmetic operations. |
Array with negative numbers | The solution should correctly handle negative numbers in the array. |
Array with duplicate elements and bad pairs exist. | The counting method correctly identifies different indices i and j even if nums[i] == nums[j] so long as i < j isn't satisfied and handles the duplicates correctly. |
Maximum array size limit reached | The solution should consider memory usage and potential out-of-memory errors when dealing with very large arrays; an iterative method with constant memory is preferable. |