1.二分查找
思路:
判断一个数是否在某个数组中,如果存在则返回这个数在数组的下标,如果不在数组中,就返回-1
一般就是通过中间值与目标值target比较,在根据比较的结果更新左右区间的范围,这是需要比较多次的过程,所以需要通过循环来实现,但是不知道需要循环几次,所以需要借助while循环来实现。需要找出循环不变量,当这个条件不满足的时候,就终止这个循环,也就是说需要知道什么时候结束,结束分两个结果,第一个就是在循环的过程中找到目标值,并返回下标之后break;第二种情况,目标值不在这个数组中,我们已经找遍了,根据循环不变量来终止这个循环,并返回-1,来宣布失败。
具体还需要分数组的情况来判断,一般分四个情况,但是常用的情况就只有两种:
左闭右开
[left,right),在这个区间内,left不可以等于right,所以循环不变量为:while(left<right),只要满足这个条件,就可以一直循环查找。
如果midle>target:
那就要更新右区间的范围,也就是更新right的值,因为midle为下标的值已经判断出来,不是我们要的数,就不要再加入它进行下一次循环了,正好right是开区间,不包含right,所以更新为right = midle
如果midle<right
需要更新左区间的范围,因为左区间为闭区间,所以更新为 left= midle - 1
左闭右闭
大致思路同上,但是更新的时候需要注意,left = midle - 1 或者是 right = midle - 1
更新的原则是已经判断为不满足条件的数,需要完全剔除,没必要再带着进行下一次的循环,也不能在更新范围的时候,剔除还没有进行判断的数,就是关于midle是否需要-1的问题,需要好好想想!
代码:
class Solution {
public int search(int[] nums, int target) {
if (target < nums[0] || target > nums[nums.length - 1]) {
return -1;
}
int left = 0;
int right = nums.length;
int mid = (left+right)/2;
while (left <= right) {
if(target==nums[mid]){
return mid;
}
if(target<nums[mid]){
right = mid-1;
mid = (left+right)/2;
}
if(target>nums[mid]){
left = mid+1;
mid =(left+right)/2;
}
}return -1;
}
}
2.移除元素:
思路:
定义一个快指针和慢指针,都先指向该数组的下标为0的位置,然后定义一个for循环,使得快指针能够不断的向后移位,每一次移位都会判断快指针所指向的数,是否满足新数组的要求(不能等于我们要移除的值),若是等于要移除的值,也就是不满足条件的值,快指针就继续移位,直接跳过该数,而慢指针不动。如果快指针所指向的数不等于我们要移除的值,将快指针指向的数值赋值给慢指针所指向的位置,然后快指针向后移位,慢指针也跟着向后移位。
代码:
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0;
for(int fast=0;fast<nums.length;fast++){
if(val!=nums[fast]){
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
}