力扣Hot100:位运算与双指针技巧精解

发布时间:2026/10/6 11:56:49

力扣Hot100:位运算与双指针技巧精解 1. 项目概述最近在整理力扣Hot100系列的第18组题目时我发现这组题目特别有意思——它们都涉及到一些巧妙的解题技巧而不是单纯的暴力解法。作为一名Java开发者我花了些时间深入研究这些题目总结出了一些实用的解题思路和代码实现。这组题目包括只出现一次的数字Single Number多数元素Majority Element颜色分类Sort Colors下一个排列Next Permutation寻找重复数Find the Duplicate Number这些题目看似简单但要想在O(n)时间复杂度和O(1)空间复杂度下解决就需要一些巧妙的技巧。下面我将逐一分析每道题目的解题思路和Java实现。2. 核心技巧解析2.1 只出现一次的数字这道题要求找出数组中唯一一个只出现一次的数字其他数字都出现两次。最直观的解法是用哈希表统计次数但这样空间复杂度是O(n)。位运算技巧 利用异或运算的性质a ^ a 0a ^ 0 a异或满足交换律和结合律因此我们可以将所有数字异或起来最终结果就是那个只出现一次的数字。public int singleNumber(int[] nums) { int result 0; for (int num : nums) { result ^ num; } return result; }注意这种方法只适用于其他数字都出现两次的情况。如果其他数字出现三次或更多次就需要其他方法了。2.2 多数元素这道题要求找出出现次数超过⌊n/2⌋的元素。同样哈希表统计是最直观的解法但需要O(n)空间。摩尔投票法 这是一个非常巧妙的算法可以在O(1)空间内解决问题初始化候选人和计数器遍历数组如果计数器为0选择当前元素作为候选人如果当前元素等于候选人计数器加1否则计数器减1最后的候选人就是多数元素public int majorityElement(int[] nums) { int count 0; Integer candidate null; for (int num : nums) { if (count 0) { candidate num; } count (num candidate) ? 1 : -1; } return candidate; }注意这个方法的前提是多数元素一定存在。如果可能不存在需要最后再验证一次。2.3 颜色分类这道题要求将只包含0、1、2的数组原地排序。不能使用排序函数且要一趟扫描完成。三指针法left指针指向0的右边界right指针指向2的左边界curr指针用于遍历public void sortColors(int[] nums) { int left 0, right nums.length - 1; int curr 0; while (curr right) { if (nums[curr] 0) { swap(nums, left, curr); } else if (nums[curr] 2) { swap(nums, curr, right--); } else { curr; } } } private void swap(int[] nums, int i, int j) { int temp nums[i]; nums[i] nums[j]; nums[j] temp; }注意当nums[curr]2时curr不能自增因为交换过来的元素可能是0或1需要再次检查。2.4 下一个排列这道题要求找到给定数字序列的下一个更大的排列。如果没有更大的排列就返回最小的排列。算法步骤从后向前找第一个降序的位置i如果找到从后向前找第一个大于nums[i]的数nums[j]交换nums[i]和nums[j]反转i1到末尾的部分public void nextPermutation(int[] nums) { int i nums.length - 2; while (i 0 nums[i] nums[i 1]) { i--; } if (i 0) { int j nums.length - 1; while (j 0 nums[j] nums[i]) { j--; } swap(nums, i, j); } reverse(nums, i 1); } private void reverse(int[] nums, int start) { int i start, j nums.length - 1; while (i j) { swap(nums, i, j); i; j--; } }注意这个算法的时间复杂度是O(n)空间复杂度是O(1)非常高效。2.5 寻找重复数这道题给定一个包含n1个整数的数组数字在1到n之间有且只有一个重复的数字找出它。快慢指针法 将数组视为链表数组值表示下一个节点的索引。因为有重复数字所以链表一定有环。public int findDuplicate(int[] nums) { int slow nums[0]; int fast nums[0]; do { slow nums[slow]; fast nums[nums[fast]]; } while (slow ! fast); slow nums[0]; while (slow ! fast) { slow nums[slow]; fast nums[fast]; } return slow; }注意这个方法修改了Floyd判圈算法非常巧妙。时间复杂度O(n)空间复杂度O(1)。3. 解题技巧总结3.1 位运算的妙用位运算在算法题中经常能带来意想不到的简洁解法。除了异或运算其他位运算也很有用与运算()判断奇偶、取特定位或运算(|)设置特定位非运算(~)取反左移()、右移()快速乘除23.2 双指针技巧双指针是解决数组/链表问题的利器常见模式有同向双指针快慢指针对向双指针从两端向中间移动分离双指针一个指针遍历一个指针记录位置3.3 原地算法当题目要求O(1)空间复杂度时考虑利用输入数据本身存储中间结果交换元素位置而不是使用额外空间使用位运算压缩信息3.4 数学思维很多算法题本质上是数学问题比如排列组合问题数论问题质数、公约数等几何问题概率问题培养数学思维能帮助发现更优解法。4. Java实现注意事项4.1 边界条件处理在实现这些算法时要特别注意边界条件空数组或单元素数组所有元素相同的情况最大值/最小值边界整数溢出问题4.2 代码优化技巧尽量减少不必要的变量使用位运算代替算术运算避免重复计算合理使用循环和递归4.3 测试用例设计好的测试用例应该包括常规情况边界情况极端情况特殊输入例如对于只出现一次的数字正常情况[2,2,1]边界情况[1]特殊情况[4,1,2,1,2]5. 常见错误与调试技巧5.1 位运算常见错误忘记初始化结果变量混淆位运算符优先级忽略整数溢出错误处理负数5.2 双指针常见错误指针移动条件错误边界处理不当循环终止条件错误指针越界5.3 调试技巧打印中间变量值使用小规模测试数据逐步验证算法步骤画图辅助理解6. 性能优化建议6.1 时间复杂度优化分析问题特性寻找数学规律使用更高效的数据结构减少不必要的计算利用问题约束条件6.2 空间复杂度优化原地修改输入数据重用变量使用位运算压缩信息避免创建不必要的数据结构6.3 Java特定优化使用基本类型而非包装类避免自动装箱/拆箱合理使用StringBuilder注意对象创建开销7. 扩展思考7.1 相关题目推荐只出现一次的数字II其他数字出现三次多数元素II找出所有出现超过⌊n/3⌋的元素荷兰国旗问题颜色分类的变种上一个排列寻找所有重复数7.2 实际应用场景位运算加密算法、压缩算法、位图处理摩尔投票大数据流中的频繁项挖掘双指针字符串处理、图像处理排列生成密码破解、组合优化7.3 进阶学习资源《算法导论》中的位运算和排列组合章节LeetCode上的类似题目计算机程序设计艺术中的相关算法在线算法竞赛平台的练习题8. 个人实战心得在实际刷题过程中我发现这些技巧类题目有几个共同特点表面简单但暗藏玄机乍一看可能觉得很简单但要达到最优解需要深入思考。数学思维是关键很多最优解法都基于数学原理而不仅仅是编程技巧。模式识别很重要一旦掌握了几种常见技巧类似题目就能快速识别并解决。边界条件容易出错即使算法正确边界条件处理不当也会导致失败。我建议在练习这类题目时先自己思考不要急于看答案理解而不仅是记住解法多做变种题目巩固理解记录自己的错误和心得最后这些技巧不仅在面试中有用在实际开发中遇到类似问题时也能帮助我们写出更高效的代码。
延伸阅读

更多相关文章

2026/10/5 8:55:34

VS Code终端自动激活Python虚拟环境:Conda与Venv智能检测方案

1. 项目缘起:一个被重复点击浪费掉的时间作为一名长期在Windows上进行Python开发的工程师,我每天都要和VS Code的终端打交道。最让我头疼的场景莫过于:打开一个项目,需要先激活Conda环境;再打开另一个项目,…

2026/10/4 21:23:06

BetterNCM安装器:3分钟打造个性化网易云音乐体验的终极方案

BetterNCM安装器:3分钟打造个性化网易云音乐体验的终极方案 【免费下载链接】BetterNCM-Installer 一键安装 Better 系软件 项目地址: https://gitcode.com/gh_mirrors/be/BetterNCM-Installer 还在为网易云音乐功能单一而烦恼吗?BetterNCM安装器…

2026/10/6 19:14:37

Windows下Maven安装与配置全指南:环境变量、镜像与IDEA实战

在Windows上装Maven,大概是很多Java开发者入门时遇到的第一道“假门槛”。说它假,是因为步骤翻来覆去就那么几招:下载解压、配环境变量、改一下settings.xml。说它是门槛,是因为其中任何一步走偏,后面就会冒出一连串莫…

2026/10/6 19:14:37

LabVIEW基于SQLite实现用户管理部门管理模块的设计与优化

做LabVIEW上位机这些年,我越来越觉得“用户管理”“部门管理”这两个模块是设备管理系统里最容易被低估的部分。最近我正好在一套测试工站管理软件里完整实现了基于SQLite的用户管理部门管理模块,涉及数据库表设计、LabVIEW调用SQLite DLL、批量数据操作…

2026/10/6 19:14:37

智能工厂MES数字化一体化落地路线图:ISA-95架构与若依框架实战

简介:这份PPT资源面向制造业信息化从业者、MES实施顾问及工厂数字化转型负责人,围绕智能工厂MES数字化一体化解决方案展开,系统梳理了从可视化工厂到数字化工厂再到智能化工厂的三阶段演进路径。内容涵盖智慧工厂整体方案、高效操作与柔性化生…

2026/10/6 19:14:37

C# TCP粘包分包问题详解:消息边界设计与拆包器实战

在做C#上位机和设备通信时,我估计你迟早会碰到这种场景:设备下发一条数据帧,程序收是收到了,但解析出来却是乱码;或者明明只发了一条指令,接收方却一下蹦出来两帧内容;又或者一条完整的数据被拆…

2026/10/6 19:09:36

禁用a标签跳转全攻略:preventDefault与锚点定位实战

1. 需求解构&#xff1a;为什么总想管住a标签那一下跳转 先说个早年间我真实踩过的坑。做一个管理后台的表格&#xff0c;列表里每一行都有“编辑”“删除”两个操作&#xff0c;当时图省事直接写了 <a href"edit.html?id1">编辑</a> 这种结构&#x…

2026/10/5 6:32:56

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起&#xff1a;为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高&#xff0c;很多人第一次听到会以为是某个新模型的名字&#xff0c;其实它更像是一种思路——把Jev模型的能力当作底座&#xff0c;通过Agent的方式去接管浏览器&#xf…

2026/10/6 4:01:51

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同"&#xff1a;多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西&#xff0c;大概率会有一种感觉&#xff1a;单个 Agent 能做的事情&#xff0c;其实很快就摸到天花板了。你给它一个提示词&#xff0c;挂几个工…

2026/10/6 17:46:51

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 0:03:23

MR25H40CDF+STM32F031C6工业级高可靠数据存储方案

1. 项目概述&#xff1a;为什么在工业现场非得用 MR25H40CDF 配 STM32F031C6 做数据存储&#xff1f;在工厂产线的 PLC 控制柜里、在风电变流器的散热片背面、在矿井监测终端的金属外壳下&#xff0c;你经常能看到一块指甲盖大小的黑色芯片——它既不是 Flash&#xff0c;也不是…

2026/10/6 0:03:23

MRAM+STM32工业断电数据保全实战指南

1. 项目概述&#xff1a;为什么在工业现场非得用 MR25H40CDF 配 STM32F031C6 做数据存储&#xff1f;在工厂产线的PLC柜里、在野外无人值守的环境监测终端里、在高速运转的包装机控制板上&#xff0c;你经常能看到一块指甲盖大小的黑色芯片&#xff0c;旁边贴着“MR25H40CDF”丝…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑