3.24 位运算,哈希,前缀

news/2025/3/26 18:57:13/文章来源: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…

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开发系统的基本步骤,仅供…

一文速通Python并行计算:02 Python多线程编程-threading模块、线程的创建和查询与守护线程

本文介绍了Python threading模块的核心功能,包括线程创建与管理、线程状态监控以及守护线程的特殊应用,重点讲解了Thread类的实例化方法、获取当前线程信息、检测线程存活状态,以及如何实现后台线程。一文速通 Python 并行计算:02 Python 多线程编程-threading 模块、线程的…

编程神器Trae:当我用上后,才知道自己的创造力被低估了多少

"AI会让每个人都能成为工具创造者,打破你能力边界,有时候只需要一个想法。" AI粉嫩特攻队,2025年3月23日。 前几天参加了一场行业闭门研讨会,满满1个半小时的干货演讲让我收获颇丰。会后,我迫不及待地想将录音整理成文字,方便日后回顾。却被提示"文件过大…

20244212喻浩川《Python程序设计》实验一报告

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

龙哥量化:deepseek写公式是需要思路的, 我整理的公式思路,请点赞收藏, 我持续更新ing

龙哥微信:Long622889代写技术指标_选股公式: 通达信,同花顺,东方财富,大智慧,文华,博易,飞狐代写量化策略: TB交易开拓者,文华8,金字塔AI写代码,很多朋友都试过了 deepseek,腾讯元宝,通义千问,豆包,chatgpt,通达信内嵌AI写公式,同花顺内嵌AI写公式,等等,写…

SciTech-EECS-Circuits-电路稳定性: 温度补偿 的几种方式对比: 响应时问、精度、动态范围、线性度、稳定度

电路稳定性: 温度稳定性 测试的几种方式:电吹风加热 冰箱(-5度) + 烤箱(50度/70度)改进 "文氏电桥振荡" 电路 的“热稳定性温度补偿” 网上找来找去,都是用FET(场效应管)做成"压控电阻"控制 "振荡器"的"增益",达到稳幅的目的。 但电…

SpringBoot3+Vue3实现查询功能

安装axios封装前后端对接数据工具npm i axios -S通过requst.js工具类发起请求import axios from "axios"; import {ElMessage} from "element-plus";const request = axios.create({baseURL:http://localhost:8080,//后端统一的请求地址timeout:30000 //后…

Apache Echarts 入门学习 -2025/3/24

介绍 一种数据可视化技术echats官方文档: https://echarts.apache.org/handbook/zh/get-started/ <!DOCTYPE html> <html> <head><meta charset="utf-8"><title>第一个 ECharts 实例</title><!-- 引入 echarts.js --><…