这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战
双指针的算法可以说是在算法题里面占据的比例相对比较大的,也是门槛比较低的。
双指针
所谓的双指针,指的就是在遍历对象的时候,利用两个不同的指针分别指向两个不同的变量,从而达到相应的目的。常见的双指针分为两种:
- 快慢指针:常用于遍历链表等,辨别是否存在环 —— 通过数学的快慢跑步举例,速度快的一定会追上速度慢的并套圈。
- 对撞指针:常用于遍历数组集合等,位置对换等操作。
有序数组的平方
该题出自力扣的977题——有序数组的平方【简单题】
审题
给你一个按 非递减顺序 排序的整数数组
nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
- 题意也很简单,返回数组的平方数组。
- 抓住题目的关键:
- 非递减顺序的整数数组:也就是说数组时升序的
- 其中存在关键,数组内的元素存在负数,也就是需要判断负数后的平方 是否 > 最大值
- 利用双指针实现
- 定义一个新的数组,长度为原数组的长度
- for循环,利用对撞指针,左指针指向 下标 0,右指针指向下标 长度 -1;
- 定义一个变量,指向新数组的最后一位,倒序填入数据
编码
public int[] sortedSquares(int[] nums) {
int n = nums.length;
int[] ans = new int[n];
for(int i =0,j=n-1,pos = n -1;i<=j;){
int maxi = nums[i] * nums[i],maxj = nums[j] * nums[j];
if(maxi > maxj){
ans[pos] = maxi;
i++;
}else{
ans[pos] = maxj;
j--;
}
pos--;
}
return ans;
}
轮转数组
该题出自力扣的189题——轮转数组【中等题】
审题
给你一个数组,将数组中的元素向右轮转
k个位置,其中k是非负数。
- 该题也是可以利用双指针的对撞指针实现,但是并没有像简单题那样直接
- 轮转数组,也就是循环;可以对轮转 K值进行数组的长度取余,最终只需关注轮转一次的结果
- 轮准的实现:以数组 [1,2,3,4,5,6,7]为例,轮准 k=3
- 第一次先全局轮转
[7,6,5,4,3,2,1] - 第二次进行局部轮状
[5,6,7,4,3,2,1] - 第三次轮转
[5,6,7,1,2,3,4]
- 第一次先全局轮转
编码
public void rotate(int[] nums, int k) {
int n = nums.length;
int i = k%n;
rest(nums,0,n-1);
rest(nums,0,i-1);
rest(nums,i,n-1);
}
public void rest(int[] nums,int start,int end){
while(end > start){
int i = nums[start];
nums[start] = nums[end];
nums[end] = i;
start++;
end--;
}
}
总结
双指针的实现在日常算法题中,频率相对比较高,相对于冒泡的双重for循环来说,时间复杂度缩小了一半。但是还是需要面向业务实现,抛开业务,空谈技术就是耍流氓。