【LeetCode】1803. 统计异或值在范围内的数对有多少

1803. 统计异或值在范围内的数对有多少

题目描述

给你一个整数数组 nums (下标 从 0 开始 计数)以及两个整数:lowhigh ,请返回 漂亮数对 的数目。

漂亮数对 是一个形如 (i, j) 的数对,其中 0 <= i < j < nums.lengthlow <= (nums[i] XOR nums[j]) <= high

示例 1

输入:nums = [1,4,2,7], low = 2, high = 6
输出:6
解释:所有漂亮数对 (i, j) 列出如下:
- (0, 1): nums[0] XOR nums[1] = 5
- (0, 2): nums[0] XOR nums[2] = 3
- (0, 3): nums[0] XOR nums[3] = 6
- (1, 2): nums[1] XOR nums[2] = 6
- (1, 3): nums[1] XOR nums[3] = 3
- (2, 3): nums[2] XOR nums[3] = 5

示例 2

输入:nums = [9,8,4,2,1], low = 5, high = 14
输出:8
解释:所有漂亮数对 (i, j) 列出如下:
​​​​​ - (0, 2): nums[0] XOR nums[2] = 13
- (0, 3): nums[0] XOR nums[3] = 11
- (0, 4): nums[0] XOR nums[4] = 8
- (1, 2): nums[1] XOR nums[2] = 12
- (1, 3): nums[1] XOR nums[3] = 10
- (1, 4): nums[1] XOR nums[4] = 9
- (2, 3): nums[2] XOR nums[3] = 6
- (2, 4): nums[2] XOR nums[4] = 5

提示

  • 1 <= nums.length <= 2 * 104
  • 1 <= nums[i] <= 2 * 104
  • 1 <= low <= high <= 2 * 104

算法一:哈希表

思路

在这里插入图片描述

代码实现时,可以按照「统计前 k 个比特、统计前 k−1 个比特、统计前 k−2 个比特、……、统计前 1 个比特」进行,那么在遍历 cnt 的同时,可以把每个键都右移 1 位,从而得到下一次要统计的 cnt,这样不用重新遍历 nums,效率也更高。

收获

  • 我一开始用暴力结果,果然超时了。这道题主要考察二进制,对我来说还是太难了…之后再回来看。

算法情况

在这里插入图片描述

代码

class Solution {
public:
    int countPairs(vector<int>& nums, int low, int high) {
        int ans = 0;
        unordered_map<int, int> cnt;
        for(int x : nums) ++ cnt[x];
        for(++high; high; high>>=1, low>>=1){
            unordered_map<int, int> nxt;
            for(auto &[x, c] : cnt){
                if(high % 2 && cnt.count(x ^ (high - 1))) ans += c * cnt[x ^ (high - 1)];
                if(low % 2 && cnt.count(x ^ (low - 1))) ans -= c * cnt[x ^ (low - 1)];
                nxt[x >> 1] += c;
            }
            cnt = move(nxt);

        }
        return ans / 2;
    }
};

参考资料

  1. 不会字典树?只用哈希表也能做!(Python/Java/C++/Go)

  2. unordered_map使用详解

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值