算法专题一:双指针

ops/2025/3/17 18:53:47/

1.移动零

题目链接:283. 移动零 - 力扣(LeetCode)

我们可以定义一个dest,一个cur,dest表示数组中不为零的数的最后一位,cur用来遍历数组

class Solution {public void moveZeroes(int[] nums) {for(int cur=0,dest=-1;cur<nums.length;cur++){if(nums[cur]!=0){dest++;int tem=nums[dest];nums[dest]=nums[cur];nums[cur]=tem;}}}
}

 

2.复写零

题目链接:1089. 复写零 - 力扣(LeetCode)

按正序的方式,判断cur是否为0,如果不是cur++,dest++,如果为0,dest+=2,并且dest经过的两位都赋值为0,会导致后面的数被覆盖,所以我们需要换一种方法。

我们可以先找到最后一个复写的数

先判断cur位置的值,来决定dest走一步还是两步,然后根据dest的位置来判断是否为最后一位,不是dest最后一位,则cur++,如果dest为最后一位,那么cur现在的位置则是最后一个复写的数。

但是我们发现这样我们写的代码还是有问题

举一个例子

此时dest指向的位置已经发生了越界

所以我们需要再加上一个判断当cur(n-1)的位置为0,则cur--,dest-=2

最后我们只需要逆序进行复写就可以了

代码如下:

class Solution {public void duplicateZeros(int[] arr) {int cur=0;int dest=-1;int n=arr.length;while(cur<n){if(arr[cur]!=0){dest+=1;}else{dest+=2;}if(dest >= n - 1){break;}cur++;}if(dest==n){arr[n-1]=0;dest-=2;cur--;}while(cur>=0){if(arr[cur]!=0){arr[dest--]=arr[cur--];}else{arr[dest--]=0;arr[dest--]=0;cur--;}}}
}

 

3.快乐数 

题目链接:202. 快乐数 - 力扣(LeetCode)

 

所以我们的算法原理:可以定义一个快指针,一个慢指针,快指针每次走两步,慢指针每次走一步,直至两个指针相遇,如果相遇时的数为1,则是快乐数,如果不是1,就不是快乐数。 

代码如下:

class Solution {public int sum(int n){int sum=0;while(n!=0){int t=n%10;sum+=t*t;n/=10;}return sum;}public boolean isHappy(int n) {int slow=n;int fast=sum(n);while(slow!=fast){slow=sum(slow);fast=sum(sum(fast));}return slow==1;}
}

4.盛最多水的容器 

题目链接:11. 盛最多水的容器 - 力扣(LeetCode)

大家看到这个题目一定会想到这道题的暴力解法,套两层for循环,进行暴力枚举,但是这种解法会超时。O(n2)

我们就要需要找到其中的规律

比如这种情况:

我们从中取出一小部分进行讲解

体积无非就是长  *  宽
我们通过左右的比较,发现6比3大,我们可以将3的位置往前移动一位。

这样移动的思想就是,我们如果将6往前移动一位,无非就是三种情况

  1. 宽度减小,高度不变
  2. 宽度减小,高度也减小
  3. 宽度减小,高度不变

无论我们怎么样移动体积都会减小,所以我们每次将两边较小的进行移动。

代码如下:

class Solution {public int maxArea(int[] height) {int left=0;int right=height.length-1;int result=0;while(left < right){int v=Math.min(height[left],height[right]) * (right-left);result=Math.max(v,result);if(height[left]<height[right]){left++;}else{right--;}}return result;}
}

5.有效三角形的个数 

题目链接:611. 有效三角形的个数 - 力扣(LeetCode)

规律

class Solution {public int triangleNumber(int[] nums) {Arrays.sort(nums);int n=nums.length;int total=0;for(int i=n-1;i>=2;i--){int left=0;int right=i-1;while(left<right){if(nums[left] + nums[right]<=nums[i]){left++;}else{total+=right-left;right--;}}}return total; }
}

 

6.和为s的两个数字 

题目链接:LCR 179. 查找总价格为目标值的两个商品 - 力扣(LeetCode)

class Solution {public int[] twoSum(int[] price, int target) {int n=price.length;int left=0;int right=n-1;while(left<right){if(price[left]+price[right]<target){left++;}else if(price[left]+price[right]>target){right--;}else{return new int[]{price[left],price[right]};}}return new int[]{0};}
}

7.三数之和

题目链接:15. 三数之和 - 力扣(LeetCode) 

小优化:

class Solution {public List<List<Integer>> threeSum(int[] nums) {Arrays.sort(nums);List<List<Integer>> ret =new ArrayList<>();int n=nums.length;for(int i=0;i<n;){int left=i+1;int right=n-1;int target=-nums[i];if(nums[i]>0){break;}while(left<right){int sum=nums[left]+nums[right];if(sum>target){right--;}else if(sum<target){left++;}else{ret.add(new ArrayList<Integer>(Arrays.asList(nums[i],nums[left],nums[right])));left++;right--;while(left<right && nums[left]==nums[left-1]){left++;}while(left<right && nums[right]==nums[right+1]){right--;}}}i++;while(i<n-1 && nums[i]==nums[i-1]){i++;}}return ret;}
}

8.四数之和

题目链接: 18. 四数之和 - 力扣(LeetCode)

这个题目跟上一个题目基本一致,唯一的差别就是需要外面在套一层循环,整体思路和思想都是一样的。

注意:要把aim定义为long类型,否则会出现整数溢出的问题

class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> ret=new ArrayList<>();Arrays.sort(nums);int n=nums.length;for(int i=0;i<n;){for(int j=i+1;j<n;){int left=j+1;int right=n-1;long aim=(long)target-nums[i]-nums[j];while(left<right){int sum=nums[left]+nums[right];if(sum>aim){right--;}else if(sum<aim){left++;}else{ret.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));left++;right--;while(left<right && nums[left]==nums[left-1]){left++;}while(left<right && nums[right]==nums[right+1]){right--;}}}j++;while(j<n && nums[j]==nums[j-1]){j++;}}i++;while(i<n && nums[i]==nums[i-1]){i++;}}return ret;}
}

希望能对大家有所帮助!!! 


http://www.ppmy.cn/ops/166590.html

相关文章

Unity打包Android平台调用sherpa-onnx

https://github.com/xue-fei/sherpa-onnx-unity 最初测试了PC的Win和Linux平台&#xff0c;直接从nuget缓存包中拷贝相关文件&#xff0c;按示例写了语音转文字和文字转语音的测试代码&#xff0c;功能都正常。 然后是Android端&#xff0c;看了示例发现有编译好的jni.so之类的…

重生之我在学Vue--第14天 Vue 3 国际化(i18n)实战指南

重生之我在学Vue–第14天 Vue 3 国际化(i18n)实战指南 文章目录 重生之我在学Vue--第14天 Vue 3 国际化(i18n)实战指南前言一、Vue I18n 核心配置1.1 基础环境搭建1.2 初始化配置1.3 全局挂载 二、多语言实现方案2.1 基础使用2.2 动态切换语言2.3 高级功能实现复数处理日期/货币…

sql靶场--布尔盲注(第八关)保姆级教程

目录 布尔盲注&#xff08;第八关&#xff09; 1.判断 2.确认布尔盲注 3.手工尝试布尔盲注 表名字符 表数 表名长度 表字符 字段数 字段名长度 字段字符 4.脚本布尔盲注注入 布尔盲注&#xff08;第八关&#xff09; 1.判断 布尔盲注了&#xff0c;这种页面只会有…

考研408-数据结构完整代码 线性表的顺序存储结构 - 顺序表

线性表的顺序存储结构 - 顺序表 1. 顺序表的定义 ​ 用一组地址连续的存储单元依次存储线性表的数据元素&#xff0c;从而使逻辑上相邻的两个元素在物理位置上也相邻 2. 顺序表的特点 随机访问&#xff1a; 即通过首地址和元素序号可以在O(1) 时间内找到指定元素&#xff0…

设计模式(行为型)-备忘录模式

目录 定义 类图 角色 角色详解 &#xff08;一&#xff09;发起人角色&#xff08;Originator&#xff09;​ &#xff08;二&#xff09;备忘录角色&#xff08;Memento&#xff09;​ &#xff08;三&#xff09;备忘录管理员角色&#xff08;Caretaker&#xff09;​…

django 运行时仅显示500 但是不提示其他内容 如何令其显示更多错误信息

在 Django 中&#xff0c;当发生 500 错误时默认仅显示简单的错误页面&#xff08;不包含堆栈跟踪等详细信息&#xff09;&#xff0c;这通常是因为 生产环境配置禁用了调试模式&#xff08;DEBUG False&#xff09;。以下是逐步解决方案&#xff0c;帮助你显示更详细的错误信…

蓝桥杯学习-08序列二分

08序列二分 序列二分应用的序列必须是递增或递减&#xff0c;但可以非严格 只要r是mid-1&#xff0c;就对应mid&#xff08;lr1&#xff09;/2 例题1-模板题&#xff08;18492&#xff09; 注意这里是个递增的序列。 解答 import java.util.Scanner; import java.util.Str…

SQL--算术运算符

过滤信息&#xff1a;where SELECT * FROM employees where department_id90; where紧随from语句 算术运算符&#xff1a; 加法运算符&#xff08;&#xff09; 用于计算两个数值的和。 示例&#xff1a; SELECT 1001 FROM dual; /*结果为101*/ SELECT 100A FROM dual; /*…