1.二分法概述
在一个有序数组里面找一个数target,在数组中找一个middle位,大了的话往左边找,小了的话往右边找。
2.解题思路
一般就看区间。区间可以是两边都是闭区间[a,b],或者左边闭合右边开[a,b)。其他的区间形式比较少去写。
2.1 先看都是闭区间的写法
public int allClose(int[] nums, int target){
int left = 0; //左边闭合,所以左边加进来
int right = nums.length - 1; //右边闭合,也就是右边的数据是有意义的,要-1,不然越界就是没意义的。
while(left <= right){ //这里是<=,比如[1]符合左闭合右闭合,1可以等于1,
int middle = (left + right) / 2; //求中间值
if(nums[middle] < target){ // 中间比target小,区间left要往右边挪,由于左边必须闭合,是有意义的,而我们已经知道middle这个位置压根不是要找的,没有意义,所以要加1,不要把没有意义的放入下一次while
left = middle + 1;
}else if(nums[middle] > target){ //同理,比target大的话说明right要往左边挪,去掉没有意义的middle
right = middle - 1;
}else{
return middle; //相等就返回咯
}
}
return -1; //找不到回个-1
}
再看看左闭右开
public int openRight(int[] nums, int target){
int left = 0;
int right = nums.length; //右开代表右边可以是没意义的,所以直接下标length
while(left < right){
int middle = (left + right) / 2;
if(nums[middle] < target){ //比target小,left往右走,由于left闭合,middle位的没有意义,那么left往右+1.
left = middle + 1;
}else if(nums[middle] > target){//这个时候由于右边不闭合,也就是右边可以有个没啥意义的,那么就等于middle
right = middle ;
}else{
return middle;
}
}
return -1;
}
然后是leetcode27
其实就是让快的去找,可以的就【赋值】给慢的,注意是赋值。
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0;
for(int fast=0; fast<nums.length; fast++){
if(nums[fast] != val){
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
}