【每日一题Day90】LC1814统计一个数组中好对子的数目 | 哈希表

统计一个数组中好对子的数目【LC1814】

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.

  • 思路:如果两个数满足好对子,那么这两个数反转后的变化量相同。因此可以使用哈希表存放反转后的变化量及其次数 c o u n t count count,该变化量存在的所有好对子个数为 c o u n t ∗ ( c o u n t − 1 ) / 2 count*(count-1)/2 count(count1)/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类型变量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值