3.24 位运算,哈希,前缀

news/2025/4/19 3:28:58/文章来源:https://www.cnblogs.com/fufuaifufu/p/18790505

题目链接

题目背景
我们需要解决的问题是:给定一个整数数组 nums 和两个整数 low 和 high,统计满足条件的“漂亮数对” (i, j) 的数量,其中:
0 <= i < j < nums.length
low <= (nums[i] XOR nums[j]) <= high
简单来说,我们要找所有满足条件的数对 (i, j),使得 nums[i] 和 nums[j] 的异或值在 [low, high] 范围内.
什么是异或(XOR)?
异或是一种位运算,符号是 ^.它的规则是:如果两个比特位相同,结果是 0;如果不同,结果是 1.比如:
5 ^ 3:
5 的二进制是 101
3 的二进制是 011
按位异或:101 ^ 011 = 110,即十进制的 6
异或的一个重要性质是:如果 x ^ y = t,那么 y = x ^ t。这在题目中会很有用
暴力解法:O(n²) 的复杂度
最直观的思路是两重循环,枚举所有可能的数对 (i, j),计算 nums[i] ^ nums[j],然后判断是否在 [low, high] 范围内:

int countPairs(vector<int>& nums, int low, int high) {int ans = 0;for (int i = 0; i < nums.size(); i++) {for (int j = i + 1; j < nums.size(); j++) {int xorVal = nums[i] ^ nums[j];if (xorVal >= low && xorVal <= high) {ans++;}}}return ans;
}

但题目中 nums 的长度可以达到 2 * 10^4,这种方法的时间复杂度是 O(n²),会超时.我们需要更高效的解法

高效解法:利用位运算和前缀统计
题目中 nums[i] 和 low、high 的范围都在 2 * 10^4 内,意味着它们的二进制表示最多有 15 位(因为 2^14 = 16384 < 2 * 10^4 < 2^15 = 32768)。我们可以利用位运算,从高位到低位逐步统计

核心思想:从高位到低位统计
我们将问题转化为:统计异或值小于某个数 t 的数对数量。最终答案是:
异或值小于 high + 1 的数对数量 减去 异或值小于 low 的数对数量。
即:countPairs(nums, low, high) = countLessThan(high + 1) - countLessThan(low)

如何统计异或值小于 t 的数对数量?
我们从高位到低位(从第 14 位到第 0 位)逐步统计:
用哈希表统计前缀:用一个哈希表 cnt 记录当前前缀的出现次.初始时,cnt[x] 表示 nums 中值为 x 的数的个数
逐位处理:对于当前位(第 k 位),我们只关心 nums[i] 的前 k 位,忽略低位.
计算贡献:如果 t 的第 k 位是 1,我们需要统计满足条件的数对;如果 t 的第 k 位是 0,则跳过.
更新前缀:将 cnt 中的每个键右移一位(即忽略最低位),进入下一轮统计。
举例说明
以 [0, 10100] 为例(10100 是二进制,表示十进制的 20),我们统计异或值小于 10100 的数对数量:
第 4 位(最高位):t = 10100,第 4 位是 1
假设 nums 中有 2 个数的前 4 位是 10000,3 个数的前 4 位是 00000
我们需要统计异或值的前 4 位是 10000 的数对数量
对于 x = 10000,x ^ t = 10000 ^ 10000 = 00000,cnt[00000] = 3,所以贡献是 2 * 3 = 6
类似地计算其他前缀。
右移:将 cnt 中的键右移一位,进入第 3 位统计

为什么可以这样统计?
当我们只看前 k 位时,低位可以是任意值(0 或 1),这相当于统计了所有可能的低位组合
比如,统计前 3 位时,t = 100 实际上包含了 t = 10000, 10001, 10010, 10011 的所有情况
代码实现

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) {// 如果 high 的当前位是 1,计算贡献if (high & 1 && cnt.count(x ^ (high - 1))) {ans += c * cnt[x ^ (high - 1)];}// 如果 low 的当前位是 1,减去贡献if (low & 1 && cnt.count(x ^ (low - 1))) {ans -= c * cnt[x ^ (low - 1)];}// 右移一位,更新前缀nxt[x >> 1] += c;}cnt = move(nxt);}// 每对被统计了两次((i, j) 和 (j, i)),所以除以 2return ans / 2;}
};

复杂度分析
时间复杂度:O(n + n * log U),其中 U = max(nums)。log U 是因为我们需要处理 U 的每一位(最多 15 位)
思路来源:灵神题解 有点赶了就这样吧

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/905102.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kioptrix Level_1

Kioptrix Level 1.1 靶场配置 导入靶场时先将vmx后缀文件中的带有ethernet0的配置行全部删除,再导入靶场,添加一个网络适配器即可 信息收集 查找目标主机ip ┌──(root㉿kali)-[~] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:84:b2:cc, IPv4: 192.168…

selenium之八大定位

八大定位 今天我们来学一学,selenium有名的八大定位方式;都有哪八个呢,下面我先列出来;之后再一个一个的实践id,通过id定位元素 name,通过name定位 class_name,通过class类名定位 tag_name,通过标签名称 link_text,通过链接文本 partial_link_text,通过部分链接文本 …

NAS配置iCloudpd

附上链接【教程】使用icloudpd自动同步iCloud照片 纠正两个错误: 1)sync-icloud.sh --Initialise 原文写的是sync-icloud.sh –Initialise是错误的,现在的版本应该如上 需要-- 不然你就会反复出现2分钟后重试的问题 2)文中的 *** 这步很重要!!!成功后,你会发现 config …

滴滴数据仓库工程师面试题

‌一、数据仓库基础与建模‌‌数仓分层设计‌请描述滴滴数仓分层架构及各层核心作用(如ODS、DWD、DWS、ADS)‌。 ‌1. ODS(Operational Data Store)层:原始数据层‌‌数据内容‌:直接从业务系统抽取的原始数据,包括订单流水、用户行为日志、司机接单记录、GPS轨迹等。‌…

20244209韩仕炜《Python程序设计》实验一报告

课程:《Python程序设计》 班级: 2442 姓名:韩仕炜 实验教师:王志强 学号:20244209 实验日期:2025年3月24日 必修/选修:专选课 1. 实验内容 1.熟悉Python开发环境; 2.练习Python运行、调试技能; 3.编写程序,练习变量和类型、字符串、对象、缩进和注释等; 4.编写一…

E1. Canteen (Easy Version)E2 Canteen (Hard Version) 对于旋转操作的深入理解

E1. Canteen (Easy Version) 题解:二分查找 + 模拟 本文大量学习了jiangly的代码对其进行详细的解析并作图对其进行解释 题目链接 深入解析:前缀和最小值旋转的直观意义一、前缀和曲线的数学本质 我们定义前缀和数组为: pre[i+1] = pre[i] + a[i] - b[i]这一公式的物理意义是…

20244209 2024-2025-2 《Python程序设计》实验一报告

课程:《Python程序设计》 班级: 2442 姓名:韩仕炜 实验教师:王志强 学号:20244209 实验日期:2025年3月24日 必修/选修:专选课 1. 实验内容 1.熟悉Python开发环境; 2.练习Python运行、调试技能; 3.编写程序,练习变量和类型、字符串、对象、缩进和注释等; 4.编写一…

ASP.NET Core WebApi+React UI开发入门详解

在前段时间,有粉丝反馈能否写一篇基于ASP.NET Core Web Api+React UI进行Web开发的文章,经过查阅相关资料,发现Visual Studio 2022已经集成相关模板,可以在Visual Studio中直接创建项目项目,今天以一个小例子,简述ASP.NET Core Web Api+React UI开发系统的基本步骤,仅供…