文章目录
一、认识左右指针
本文讲的左右指针是双指针技巧中主要的一种。其中二分查找也是左右指针常用的一种,在后面会进行详细探讨,这里只分析几个普遍的例子。左右指针其原理是将left和right同时放于数组的中点相背而行(类似于二分查找),或是将两者放于数组的两端相向而行,其特点在于结构的对称性。
二、算法运用
1.两数之和
下面选用力扣的第 167 题「两数之和 」练习,详情请读者自动跳转至原题。
该题的思路类似于二分查找,题目告诉我们此数组已经按非递减有序排列,那么在此我们选择将left和right放于数组两端。如果两数之和大于target,则rigth左移;反之,则left右移,直至两指针相遇。
代码如下(示例):
class Solution {
public int[] twoSum(int[] numbers, int target) {
int left=0,right=numbers.length-1;
while(left<right){
int sum=numbers[left]+numbers[right];
if(sum<target){
left++;//增大sum
}
else if(sum>target){
right--;//减小sum
}
else if(sum==target){
return new int[]{left+1,right+1};}//题目要求索引从1开始
}
return new int[]{};
}
}
2.反转字符串
下面选用力扣的第 344 题「反转字符串」练习,详情请读者自动跳转至原题。
遇到反转类型的题目,就应想到用左右指针将首尾两端换位,用temp作为一个存储位,便于两者互换。
代码如下(示例):
class Solution {
public void reverseString(char[] s) {
int left=0,right=s.length-1;
while(left<right){
char temp=s[left];
s[left]=s[right];
s[right]=temp;
left++;
right--;
}
}
}
3.回文串判断
下面选用力扣的第 5 题「最长回文子串」练习,详情请读者自动跳转至原题。
该题应从中心入手,其核心在于从中心向两端检索,难点在于中心字符的设定,如果数组长度为奇数,则输入相同的left和right;反之,则输入相邻的left和right。
代码如下(示例):
class Solution {
public String longestPalindrome(String s) {
String res="";
for(int i=0;i<s.length();i++){
String s1=palindrome(s,i,i);//奇数型返回最长回文串
String s2=palindrome(s,i,i+1);//偶数型返回最长回文串
//选择最长回文串
res=res.length()>s1.length()?res:s1;
res=res.length()>s2.length()?res:s2;
}
return res;
}
String palindrome(String s,int left,int right){
while(left>=0&&right<s.length()&&s.charAt(left)==s.charAt(right)){//定义范围,判断回文串
left--;
right++;
}
return s.substring(left+1,right);//返回最长回文串
}
}
总结
左右指针的核心思想在于从中心到两端或从两端到中心,对条件进行检索,其特点在于对称性,考虑情况主要从这一点入手,同时要考虑好数组是奇数还是偶数,解决办法是判断两指针是放在一起的还是相邻的。