统计一个数组中好对子的数目【LC1814】
You are given an array
nums
that consists of non-negative integers. Let us definerev(x)
as the reverse of the non-negative integerx
. For example,rev(123) = 321
, andrev(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
.
-
思路:如果两个数满足好对子,那么这两个数反转后的变化量相同。因此可以使用哈希表存放反转后的变化量及其次数 c o u n t count count,该变化量存在的所有好对子个数为 c o u n t ∗ ( c o u n t − 1 ) / 2 count*(count-1)/2 count∗(count−1)/2
-
实现
class Solution { public int countNicePairs(int[] nums) { int MOD = (int)(1e9 + 7); Map<Integer,Long> valToCount = new HashMap<>(); for (int num : nums){ int change = num - rev(num); valToCount.put(change, valToCount.getOrDefault(change, 0L) + 1); } long res = 0; for (long count : valToCount.keySet()){ res = (res + count * (count - 1) / 2) % MOD; } return (int)res; } public int rev(int num){ int res = 0; while (num != 0){ res = res * 10 + num % 10; num /= 10; } return res; } }
- 复杂度
- 时间复杂度: O ( n l o g m + n ) O(nlogm+n) O(nlogm+n), n n n为数组长度,对数组中每个数求取变化量放入哈希表的时间复杂度为 O ( n l o g m ) O(nlogm) O(nlogm)
- 空间复杂度: O ( n ) O(n) O(n)
- 复杂度
-
优化:一次遍历,由于哈希表里保存的是以前某个变化量出现的次数,因此可以直接累加该变化量以前的出现次数 c o u n t count count,即为以当前数 x x x为 j j j,数组中共有 c o u n t count count个 i i i
-
实现
class Solution { public int countNicePairs(int[] nums) { int MOD = (int)(1e9 + 7); Map<Integer,Integer> valToCount = new HashMap<>(); int res = 0; for (int num : nums){ int change = num - rev(num); res = (res + valToCount.getOrDefault(change, 0)) % MOD; valToCount.put(change, valToCount.getOrDefault(change, 0) + 1); } return res; } public int rev(int num){ int res = 0; while (num != 0){ res = res * 10 + num % 10; num /= 10; } return res; } }
- 复杂度
- 时间复杂度: O ( n l o g m ) O(nlogm) O(nlogm), n n n为数组长度, m m m为数组中的最大值
- 空间复杂度: O ( n ) O(n) O(n)
- 耗费时间多于先存储后计算,猜测原因未反复累加取余耗费的时间较高。
- 空间优于先存储后计算,因为没有使用long类型变量
- 复杂度