1814. 统计一个数组中好对子的数目
LeetCode: 1814. 统计一个数组中好对子的数目
中等 \color{#FFB800}{中等} 中等
给你一个数组
nums
,数组中只包含非负整数。定义rev(x)
的值为将整数x
各个数字位反转得到的结果。比方说rev(123) = 321
,rev(120) = 21
。我们称满足下面条件的下标对(i, j)
是 好的 :
0 <= i < j < nums.length
nums[i] + rev(nums[j]) == nums[j] + rev(nums[i])
请你返回好下标对的数目。由于结果可能会很大,请将结果对
10^9 + 7
取余 后返回。
示例 1:
输入:nums = [42,11,1,97]
输出:2
解释:两个坐标对为:
- (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 。
示例 2:
输入:nums = [13,10,35,24,76]
输出:4
提示:
1 <= nums.length <= 10^5
0 <= nums[i] <= 10^9
方法1:哈希表
对题中的等式进行移项,可以得到:
nums[i] - rev(nums[i]) == nums[j] - rev(nums[j])
即两数若与各自反转结果的 差值 相等,则为 好对子 。
遍历数组 nums
的过程中,使用哈希表记录每一个数所对应的 差值 出现过的次数,设某差值的出现次数为 k
。当该差值再次出现时,则代表又找到了 k
对 好对子 ,将 k
加入计数,再将 k + 1
赋给 k
,继续遍历。
求余:和的余数 等于 余数的和再求余
#include <vector>
#include <unordered_map>
using namespace std;
class Solution
{
public:
int countNicePairs(const vector<int> &nums)
{
constexpr int MOD = 1000000007;
int count = 0;
unordered_map<int, int> hashmap;
for (const int &num : nums)
{
int temp = num, rev = 0;
while (temp != 0)
{
rev = rev * 10 + temp % 10;
temp /= 10;
}
count = (count + hashmap[num - rev]) % MOD;
hashmap[num - rev]++;
}
return count;
}
};
复杂度分析:
-
时间复杂度: O ( n × log C ) O(n \times \log{C}) O(n×logC)。其中,
n
为数组nums
的长度,C
为数组nums
中数字的范围。反转数位的时间复杂度为 O ( log C ) O(\log{C}) O(logC) 。 -
空间复杂度: O ( n ) O(n) O(n)。为哈希表的开销。
参考结果
Accepted
84/84 cases passed (88 ms)
Your runtime beats 94.32 % of cpp submissions
Your memory usage beats 67.05 % of cpp submissions (55.4 MB)