1.移除有序数组中的重复项和移除元素
思想一样但是细节不一样
思想一样就是
设置快慢指针,快指针在前面探路,遇到不相同元素就让慢指针移动一步和交换数据
细节不一样就是
移除有序数组中的重复项就是先让慢指针先走一步再交换(因为要保证重复项有一个留下)(而这一步也决定了 返回的是slow+1),遇到不相同元素是指快慢指针所指元素不同。
而移除元素是先交换再走一步(这一步决定了slow),这样是为了保证需要被移除的那个元素真的被移除,遇到不相同元素是指快指针所值元素与需要移除的元素不相同
2.二分查找需注意
需要注意循环判断条件中,要注意left可以等于right,如果不等于的话那么数组中刚好只有一个元素的时候就会运行错误(不过前提是right=length-1,如果是等于length,就不需要等于了)
3.在排序数组中查找元素的第一个和最后一个位置
在找到nums[mid]==target之后,就从这个元素位置开始向左向右寻找,找不到就返回位置,要注意返回的索引位置具体指向,要不要+1,要不要-1什么的
class Solution {
public int[] searchRange(int[] nums, int target) {
int left=0;
int right=nums.length-1;
while(left<=right){
int mid=left+(right-left)/2;
if(nums[mid]==target){
int cur=left;
int start=mid-1;
int tail=mid+1;
while(start>=left&&nums[start]==target){
start--;
}
while(tail<=right&&nums[tail]==target){
tail++;
}
return new int[]{start+1,tail-1};
}else if(nums[mid]>target){
right=mid-1;
}else if(nums[mid]<target){
left=mid+1;
}
}
return new int[]{-1,-1};
}
}
4.最长回文串
注意res要初始化 “”这样就可以了
解题要点
轮流当中间的那个点 重点是如果是回文串是奇数则中间点是s[i],但是如果回文串是偶数则中间点是s[i+1]和s[i]
类比
这里跟在排序数组中查找元素的第一个和最后一个位置有点像 都是从中间向左向右查找数据,只不过这里比较特殊
如果return s.substring(left+1,right-1); 就会发生
java.lang.StringIndexOutOfBoundsException: begin 1, end 0, length 5
必须return s.substring(left+1,right);
是因为在二分查找 中有控制left<=right或者left<right吗?
这样right就不会小于left
5.区域和检索-数组不可变
这道题的关键在于前缀和
前缀和数组的特征是什么:
数组长度比原数组长1
preSum[0]=0
pre[i]=pre[i-1]+nums[i-1]
区间和就是用pre[right+1]-pre[left]
具体的分析过程
//0:-2
//1:-2+0
//2:-2+0+3
//3:-2+0+3±5
//4:-2+0+3±5+2
//5:-2+0+3±5+2±1
//[2,5] 前缀和数组索引5-1 即right-(left-1)
//但是这样左边界会发生溢出,所以我们需要让前缀数组整体向后移动
//0:0
//1:-2
//2:-2+0
//3:-2+0+3
//4:-2+0+3±5
//5:-2+0+3±5+2
//6:-2+0+3±5+2±1
//(right+1)-left