
Problem Statement
In this problem, you are provided with an array nums
containing non-negative integers. The task is to count the number of "nice" pairs (i, j)
in the array where the pair satisfies two conditions:
- The index
i
is less than indexj
(0 <= i < j < nums.length
). - The sum of the number at the ith position and the reversed number at the jth position is equal to the sum of the number at the jth position and the reversed number at the ith position (
nums[i] + rev(nums[j]) == nums[j] + rev(nums[i])
).
The function rev(x)
is defined as the reverse of the non-negative integer x
. For instance, rev(123)
would be 321
and rev(120)
would be 21
. Your goal is to return the count of such "nice" pairs. Given the potential size, the result should be returned modulo 109 + 7
to ensure the output is manageable.
Examples
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
Approach and Intuition
To solve this problem, we need to understand the condition under which a pair (i, j)
will be considered "nice." Let's break down the condition:
nums[i] + rev(nums[j]) == nums[j] + rev(nums[i])
This can be re-arranged and simplified to:
nums[i] - rev(nums[i]) == nums[j] - rev(nums[j])
This means that for any pair (i, j)
to be nice, the difference between each number and its reversal must be the same for both i
and j
. Thus, the approach involves following steps:
- Calculate
diff[i] = nums[i] - rev(nums[i])
for each indexi
. - Use a hash map to count occurrences of each unique difference.
- For each unique
diff
value, if it appearscount
times, the number of nice pairs contributed by this distinct difference iscount * (count - 1) / 2
because any two pairs having thisdiff
are nice pairs. - Sum up all contributions to get the total number of nice pairs.
- Return the total count modulo
109 + 7
as per the problem’s constraints.
By decomposing and abstracting the problem using the difference values, it becomes technically feasible to compute the number of nice pairs efficiently, efficient even for large arrays, as we leverage hashing to aggregate and compute pair counts based on unique differences.
Solutions
- C++
- Java
- Python
class Solution {
public:
int countNicePairs(vector<int>& nums) {
vector<int> diffs;
for (int i = 0; i < nums.size(); i++) {
diffs.push_back(nums[i] - reverseNum(nums[i]));
}
unordered_map<int, int> countMap;
int result = 0;
int MODULO = 1e9 + 7;
for (int value : diffs) {
result = (result + countMap[value]) % MODULO;
countMap[value]++;
}
return result;
}
int reverseNum(int num) {
int reversed = 0;
while (num > 0) {
reversed = reversed * 10 + num % 10;
num /= 10;
}
return reversed;
}
};
In this solution, you tackle the problem of counting nice pairs in an array using C++. Each nice pair in the array meets the criteria where nums[i] + rev(nums[j]) == nums[j] + rev(nums[i])
for i < j
.
To solve the problem efficiently:
First, compute and store the difference between each element and its reverse in a new vector called
diffs
. This transformation simplifies the original nice pairs criteria to finding pairs with equal differences, which is equivalent todiff[i] == diff[j]
.Utilize an
unordered_map
to maintain the count of each unique difference encountered. Iterate over thediffs
vector to populate this map and simultaneously compute the result. If a difference value already exists in the map, increment the result by the number of times this difference has appeared before (stored in the map).Since the counts can potentially grow large, you apply modular arithmetic (
MODULO = 1e9 + 7
) during the accumulation to ensure the result stays within bounds of typical integer limits.Define an auxiliary function,
reverseNum
, to compute the reverse of a number efficiently. This function is repeatedly called to determine the reversed values of elements as they are processed.
The key to the solution lies in recognizing that each addition to the countMap
builds a previous state for future reference, ensuring that all potential nice pairs are counted correctly as you process each number in the list. This approach ensures that your solution remains efficient and operates within O(n)
complexity given that mapping operations are average constant time, O(1).
class Solution {
public int countPairs(int[] input) {
int[] tempArray = new int[input.length];
for (int i = 0; i < input.length; i++) {
tempArray[i] = input[i] - reverse(input[i]);
}
Map<Integer, Integer> countMap = new HashMap<>();
int totalPairs = 0;
int modValue = 1000000007;
for (int value : tempArray) {
totalPairs = (totalPairs + countMap.getOrDefault(value, 0)) % modValue;
countMap.put(value, countMap.getOrDefault(value, 0) + 1);
}
return totalPairs;
}
public int reverse(int inputNum) {
int revertedNumber = 0;
while (inputNum > 0) {
revertedNumber = revertedNumber * 10 + inputNum % 10;
inputNum /= 10;
}
return revertedNumber;
}
}
The provided Java solution focuses on counting "nice" pairs in an array where a pair (i, j) is defined as nice if the difference between an element and its reversed digits at i matches this condition at j. Here's a breakdown of the implemented algorithm:
- Define an auxiliary array to store the results of the numerical operation: each element minus its reversed value.
- Utilize a HashMap to keep a count of how often each result of this operation appears in the tempArray.
- Traverse through the tempArray to compute the total nice pairs. For each element in tempArray, add to totalPairs the number of times this element has appeared before. This keeps a running total of nice pairs.
- Apply a modulo operation during additions to avoid integer overflow.
- Define a helper method 'reverse' to compute the reversed digit of an integer.
By leveraging the auxiliary array and HashMap, the solution efficiently compiles the count of nice pairs without explicitly checking every possible pair, which significantly improves the performance. This method ensures a lower time complexity by minimizing redundant computations.
class Solution:
def countPairs(self, elements: List[int]) -> int:
def reverseNumber(number):
inverted = 0
while number:
inverted = inverted * 10 + number % 10
number //= 10
return inverted
values = []
for index in range(len(elements)):
values.append(elements[index] - reverseNumber(elements[index]))
elementCount = defaultdict(int)
pairCount = 0
MODULO = 10 ** 9 + 7
for value in values:
pairCount = (pairCount + elementCount[value]) % MODULO
elementCount[value] += 1
return pairCount
The solution provided in Python is aimed at solving the problem of counting 'nice pairs' in an array. A 'nice pair' (i, j) follows the condition where i < j
and elements[i] + reversed(elements[j]) = elements[j] + reversed(elements[i])
. This can be simplified to check if elements[i] - reversed(elements[i]) = elements[j] - reversed(elements[j])
.
- Firstly, you define a helper function
reverseNumber
to reverse the digits of a given number. - You then create an array
values
to store the result ofelements[i] - reversed(elements[i])
for each element in the inputelements
. - Use a dictionary
elementCount
to keep track of the frequency of each value invalues
. - Traverse through the
values
, and for each value, update yourpairCount
by adding the current frequency of that value fromelementCount
. This step ensures checking pairs without direct comparison of indices, hence optimizing the process. - After each update of
pairCount
, increment the frequency of the current value inelementCount
. - The final answer in
pairCount
is obtained modulo (10^9 + 7) due to possible large numbers, ensuring it fits within typical integer limits in competitive programming environments.
This approach efficiently counts the 'nice pairs' by utilizing mathematical manipulation and hash mapping, thereby reducing the need for a direct O(n^2) comparison.
No comments yet.