技巧
- 快慢指针slow/fast
- 左右指针left/right
删除有序数组中的重复项
思路
- fast和slow同时指向数组首地址
- fast遍历到和slow不同的值,slow先移动到下个位置,再把fast索引处数组的值赋给slow索引
- fast遍历完数组,返回slow+1
public static int removeDuplicates(int[] nums) {
if(nums.length==0)
return 0;
int fast=0,slow=0;
while (fast<nums.length){
if(nums[fast]!=nums[slow]){
slow++;
nums[slow]=nums[fast];
}
fast++;
}
System.out.println(Arrays.toString(nums));
return slow+1;
}
移除元素
思路
- 和上一题一样,fast遍历到数值和val不同的元素,就把该值赋给slow索引下的数组元素
- 要注意的是slow接收赋值,再移动到下一个数组的位置
- 返回slow
public static int removeElement(int[] nums, int val) {
int fast=0,slow=0;
while (fast<nums.length){
if(nums[fast]!=val){
nums[slow]=nums[fast];
slow++;
}
fast++;
}
System.out.println(Arrays.toString(nums));
return slow;
}
移动零
思路
两张做法:
- 第一种借用上题思路,fast遍历到不为0的值,直接交换fast和slow索引下的值,slow++,
public static void moveZeroes(int[] nums) {
int fast=0,slow=0;
while (fast<nums.length){
if(nums[fast]!=0){
int temp=nums[slow];
nums[slow]=nums[fast];
nums[fast]=temp;
slow++;
}
fast++;
}
System.out.println(Arrays.toString(nums));
}
- 第二种利用上题代码把数组变成前面slow个元素都不为0的数组,再把剩下的元素变成0
public static void moveZeroes(int[] nums) {
int p=removeElement(nums,0);
for(;p<nums.length;p++){
nums[p]=0;
}
System.out.println(Arrays.toString(nums));
}
思路
- left、right分别指向数组首尾元素,令sum=nums[left]+nums[right]
- left<right,比较sum和target。sum>target: right–; sum<right: left++。sum==target,返回[left+1,right+1]
public static 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)
return new int[]{left+1,right+1};
else if(sum>target){
right--;
}else{
left++;
}
}
return new int[]{-1,-1};
}
反转字符串
借用上题思路,left<right,交换left和right索引处的数组值
public static 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--;
}
}
最长回文子串
思路
- 考虑两种情况:
-
- 回文子串包含奇数个字符,如aba,则中心点在字符b
- 回文子串包含偶数个字符,如cccc, 则中心点可以看成中心左右的两个c
- 针对以上两张情况,使用穷举法,分别搜索字符串的每个字符为中心点和该字符以及该字符右边最近字符为中心点存在的回文子串,即分两种情况搜索:(1) 第i个字符为中心点;(2)第i个字符与第i+1个字符为中心点
- 最后比较返回的回文子串长度,保留最长回文子串
public static String Palindrome(String s,int l,int r){
while (l>=0 && r<s.length() && s.charAt(l)==s.charAt(r)){
l--;r++;
}
return s.substring(l+1,r);
}
public static 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;
}