You are given an array nums
that consists of non-negative integers. Let us define rev(x)
as the reverse of the non-negative integer x
. For example, rev(123) = 321
, and rev(120) = 21
. A pair of indices (i, j)
is nice if it satisfies all of the following conditions:
0 <= i < j < nums.length
nums[i] + rev(nums[j]) == nums[j] + rev(nums[i])
Return the number of nice pairs of indices. Since that number can be too large, return it modulo 109 + 7
.
Example 1:
Input: nums = [42,11,1,97] Output: 2 Explanation: The two pairs are: - (0,3) : 42 + rev(97) = 42 + 79 = 121, 97 + rev(42) = 97 + 24 = 121. - (1,2) : 11 + rev(1) = 11 + 1 = 12, 1 + rev(11) = 1 + 11 = 12.
Example 2:
Input: nums = [13,10,35,24,76] Output: 4
Constraints:
1 <= nums.length <= 105
0 <= 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 counting nice pairs is straightforward. We're going to check every possible pair of numbers in the list to see if it's a 'nice pair'. If it is, we add it to our total count.
Here's how the algorithm would work step-by-step:
def count_nice_pairs_brute_force(numbers):
number_of_nice_pairs = 0
array_length = len(numbers)
for first_index in range(array_length):
for second_index in range(array_length):
# Checking every pair including itself.
first_number = numbers[first_index]
second_number = numbers[second_index]
reversed_second_number = int(str(second_number)[::-1])
# Check for the condition to increment.
if first_number + reversed_second_number == second_number + int(str(first_number)[::-1]):
number_of_nice_pairs += 1
# Divide by two to avoid overcounting, since pairs are counted twice.
number_of_nice_pairs = number_of_nice_pairs // 2
return number_of_nice_pairs
To find nice pairs efficiently, we need to avoid comparing every single pair. The key idea is to transform the problem into a counting problem using a clever mathematical trick, then use a tool to count things efficiently.
Here's how the algorithm would work step-by-step:
def count_nice_pairs(numbers):
differences = {}
count_of_nice_pairs = 0
for number in numbers:
number_reversed = int(str(number)[::-1])
difference = number - number_reversed
# Use a dictionary to count the occurrences of each difference
if difference in differences:
differences[difference] += 1
else:
differences[difference] = 1
# Iterate through the counts of each difference to calculate pairs
for difference_count in differences.values():
# Calculate number of pairs for each difference value
count_of_nice_pairs += (difference_count * (difference_count - 1)) // 2
return count_of_nice_pairs
Case | How to Handle |
---|---|
Null or empty input array | Return 0 immediately as no pairs can be formed. |
Array with a single element | Return 0 as a single element cannot form a pair. |
Array containing negative numbers | The reversing and addition operation should handle negative numbers correctly, so no special handling needed. |
Array containing zero | Zero reversed is zero, so handle as any normal number. |
Integer overflow during the reversing operation. | Use long to store the reversed number to prevent overflow. |
Large input array (performance) | Use HashMap to achieve an O(n) time complexity; a naive O(n^2) approach may timeout. |
Array contains duplicate numbers that form a pair with themselves | The counts of each reversed number difference in the hashmap correctly accounts for duplicate combinations. |
Extreme boundary values (Integer.MAX_VALUE and Integer.MIN_VALUE) | Ensure reversal and subtraction operations handle these without unexpected overflows by using long data type. |