2026/2/26 19:20:34
网站建设
项目流程
宿州哪家做网站好,下载的网站模板怎么用,网站开发的就业前景,php怎么创建网站【算法通关】双指针技巧深度解析#xff1a;从基础到巅峰#xff08;Java 最优解#xff09;我的主页#xff1a; 寻星探路 个人专栏#xff1a; 《JAVA#xff08;SE#xff09;----如此简单#xff01;#xff01;#xff01; 》 《从青铜到王者#xff0c;就差这…【算法通关】双指针技巧深度解析从基础到巅峰Java 最优解我的主页寻星探路个人专栏《JAVASE----如此简单 》 《从青铜到王者就差这讲数据结构》《数据库那些事》 《JavaEE 初阶启程记跟我走不踩坑》《JavaEE 进阶从架构到落地实战 》 《测试开发漫谈》《测开视角・力扣算法通关》 《从 0 到 1 刷力扣算法 代码双提升》《Python 全栈测试开发之路》没有人天生就会编程但我生来倔强寻星探路的个人简介在处理数组相关算法时双指针Two Pointers能够巧妙地利用区间单调性或位置关系将原本需要 的暴力搜索优化至 。本文精选四道经典题型附带保姆级代码注释。一、 移动零 (Move Zeroes) —— 快慢指针1. 算法思路慢指针 (slow)指向“下一个非零元素应该存放的位置”。快指针 (fast)遍历数组寻找非零元素。通过交换非零元素被“推”到前面零自然被“挤”到了后面。2. Java 代码实现classSolution{publicvoidmoveZeroes(int[]nums){// slow 指针之前不含 slow全是非零数intslow0;for(intfast0;fastnums.length;fast){// 当快指针发现非零数时if(nums[fast]!0){// 如果快慢指针不相等说明中间有 0需要交换if(fastslow){inttempnums[slow];nums[slow]nums[fast];nums[fast]temp;}// 无论是否交换slow 都要后移因为当前 slow 位置已被非零数占据slow;}}}}二、 盛最多水的容器 (Container With Most Water) —— 左右指针1. 算法思路核心原理木桶效应。容量由“短板”决定。指针移动逻辑若移动长板宽度减小高度依然受限于短板容量只会变小只有移动短板才可能换来更高的高度。2. Java 代码实现classSolution{publicintmaxArea(int[]height){intleft0,rightheight.length-1;// 定义左右边界intmax0;// 存储最大面积while(leftright){// 1. 计算当前面积宽 (right - left) * 高 (左右两端的最小值)intcurrentAreaMath.min(height[left],height[right])*(right-left);// 2. 更新全局最大面积maxMath.max(max,currentArea);// 3. 贪心策略哪边矮就移动哪边的指针if(height[left]height[right]){left;}else{right--;}}returnmax;}}三、 三数之和 (3Sum) —— 排序 左右指针1. 算法思路排序使数组有序方便使用双指针并进行去重。枚举固定第一个数a在剩下的区间里通过双指针寻找b和c使得a b c 0。2. Java 代码实现classSolution{publicListListIntegerthreeSum(int[]nums){ListListIntegeransnewArrayList();Arrays.sort(nums);// 1. 先排序intnnums.length;for(inti0;in;i){// 如果当前数大于 0由于数组有序后续三个数之和一定大于 0if(nums[i]0)break;// 2. 对第一个数 a 去重如果当前数和前一个数相同跳过if(i0nums[i]nums[i-1])continue;intlefti1,rightn-1;while(leftright){intsumnums[i]nums[left]nums[right];if(sum0){ans.add(Arrays.asList(nums[i],nums[left],nums[right]));// 3. 对第二个数 b 去重while(leftrightnums[left]nums[left1])left;// 4. 对第三个数 c 去重while(leftrightnums[right]nums[right-1])right--;left;right--;}elseif(sum0){left;// 和太小左指针右移增加数值}else{right--;// 和太大右指针左移减小数值}}}returnans;}}四、 接雨水 (Trapping Rain Water) —— 双指针巅峰1. 算法思路单点逻辑位置 能接的水 。双指针优化我们不需要预处理所有高度只需要用两个指针从两侧向中间靠拢。2. Java 代码实现classSolution{publicinttrap(int[]height){intleft0,rightheight.length-1;intleftMax0,rightMax0;// 记录左边和右边遇到的最高高度intres0;while(leftright){// 更新左右两侧目前的最高墙leftMaxMath.max(leftMax,height[left]);rightMaxMath.max(rightMax,height[right]);// 如果左边的墙比右边的墙矮// 意味着对于 left 这个点接多少水取决于左侧的 leftMax因为右侧一定有比它更高的墙if(leftMaxrightMax){res(leftMax-height[left]);left;}else{// 反之right 这个点接多少水取决于右侧的 rightMaxres(rightMax-height[right]);right--;}}returnres;}} 总结双指针解题的思考模版场景识别同向指针快慢指针常用于处理“原地修改”或“寻找循环/中点”。相向指针对撞指针常用于处理“有序数组寻找两数/多数之和”或“区间极值盛水/接水”。核心三要素指针初始化是(0, length-1)还是(0, 0)移动条件什么情况下左移什么情况下右移通常依据单调性判断。收缩条件如何有效跳过重复解去重以保证效率通过以上四道题的练习你应该能感受到双指针在降低时间复杂度方面的巨大威力。感谢你的阅读如果觉得代码注释对你有帮助欢迎点赞和收藏