704.二分查找
法一:左闭右闭
注意每次当target在nums[mid]左边时,right更新为mid-1;当target在nums[mid]右边时,left更新为mid+1。
另外,不要忘记更新mid。
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
int mid = (left+right)/2;
//搜查区间为闭区间[left,right],因此left = right的时候是有意义的
while(left <= right){
if(nums[mid] > target){
right = mid-1;//因为已经是大于了,所以nums[mid] != target,right移动到mid左边一个位置
mid = (left+right)/2;
}else if(nums[mid] < target){
left = mid + 1;
mid = (left+right)/2;
}else{
return mid;
}
}
return -1;
}
}
法二:左闭右开(思想上稍微复杂一点)
关键在于右边界为开区间,因此这个右边界的值实际上是取不到的。
if (nums[mid] > target) right 要更新为mid,target要在[left,mid)之间去寻找,实际上已经把mid索引的值排除在外,因此不需要不需要像左闭右闭一样将right更新为mid-1。
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length;//左闭右开,右边指针应该比最后一个索引大1
int mid = (left+right)/2;
while(left < right){//左闭右开时left=right是无意义的
if(nums[mid] > target){
right = mid;
mid = (left+right)/2;
}else if(nums[mid] < target){
left = mid + 1;//左边为闭区间,需要排除mid
mid = (left+right)/2;
}else{
return mid;
}
}
return -1;
}
}
#27. 移除元素
这道题卡尔哥的一句话让我豁然开朗:
快指针是用来查找哪些数组元素是我们需要的,慢指针是用来保存我们需要的值。
所以快指针应该对整个数组进行遍历,慢指针只有在找到需要的值的时候才会移动一位。
class Solution {
public int removeElement(int[] nums, int val) {
int slowIndex = 0;
int k = 0;
for(int i = 0;i < nums.length;i++){
if(nums[i] != val){
nums[slowIndex] = nums[i];
slowIndex++;
k++;//找到一个符合条件的值,k加一
}else{
continue;//如果快指针指向的是val,立刻向下一位移动
}
}
return k;
}
}