前言
今日练习:双指针:左右碰撞指针
目的:掌握左右指针向中间移动 ,最终相会的解法。
在下面这几道题中:思考不同题目中指针移动逻辑有什么区别
125:验证回文串
题目要求:
判断一个字符串是否是回文串,有两个条件限制:
1.忽略大小写
2.忽略非字母和数字
核心思路
用双指针(左右夹逼)
流程图:
1.left 从左开始
2.right 从右开始
3.跳过非字母/数字
4.比较:
转小写后是否相等
不等 → false
相等 → 继续
代码实现
java
int left=0,right=s.length()-1;
while(left<right){
//跳过非字母数字
while(left<right&&!Character.isLetterOrDigit(s.charAt(left))){
left++;
}
while(left < right && !Character.isLetterOrDigit(s.charAt(right))) {
right--;
}
//比较部分
if(Character.toLowerCase(s.charAt(left))!=
Character.toLowerCase(s.charAt(right))){
return false;
}
left++;
right--;
}
return true;
总结
理解本题流程:先跳过非字母数字,再进行比较(不看大小写)
Character.isLetterOrDigit:去除非字母数字
Character.toLowerCase:忽略大小写
344:反转字符串
题目要求:
反转字符串,条件限制:必须原地修改,不能开新数组
代码实现
java
int left=0,right=s.length-1;
while(left<right){
char temp=s[left];
s[right]=s[left];
s[right]=temp;
left++;
right--;
}
总结
无
15:三数之和
题目要求:
找出数组中所有和为 0 的三元组
核心思路
排序 + 固定一个数 + 双指针找另外两个
流程:
1.先排序
方便去重+使用双指针
2.固定第一个数i
使得:nums[left]+nums[right]=-nums[i]
3.双指针找剩下两个数
left=i+1, right=n-1
sum<0 left++
sum>0 right--;
sum==0 正确
4.去重
i去重/left /和right 去重(避免造成结果一致)
代码实现
java
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
// 去重
if (i > 0 && nums[i] == nums[i - 1]) continue;
int left = i + 1;
int right = nums.length - 1;
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum < 0) {
left++;
} else if (sum > 0) {
right--;
} else {
res.add(Arrays.asList(nums[i], nums[left], nums[right]));
// 去重(只在找到答案后)
while (left < right && nums[left] == nums[left + 1]) left++;
while (left < right && nums[right] == nums[right - 1]) right--;
left++;
right--;
}
}
}
return res;
}
}
总结
思路:固定一个i,用双指针找到符合条件的一组答案
题目要求不含重复,说明我们还需要进行去重操作
977:有序数组的平方
题目要求:
给你一个"已经排好序"的数组(可能有负数)
返回每个数的平方,并且结果也要有序
核心思路
双指针,从两边往 中间选"大的平方"
判断左平方与右平方的大小,讲大的放入
代码实现
java
public int[] sortedSquares(int[] nums) {
int n = nums.length;
int[] res = new int[n];
int left = 0, right = n - 1;
int index = n - 1;
while (left <= right) {
int l = nums[left] * nums[left];
int r = nums[right] * nums[right];
if (l > r) {
res[index] = l;
left++;
} else {
res[index] = r;
right--;
}
index--;
}
return res;
}