704.二分查找
二分查找,首先我们要确定一个使用前提:数组有序!!!
使用二分查找的关键:记住一点循环不变量,循环最初左右指针的初始位置、while循环中的判断条件、while循环中条件判断后指针的移动方式,这些都是关键点,搞清楚这些,二分查找也就算是通关了。
首先是左闭右闭的实现方式:
class Solution {
public int search(int[] nums, int target) {
int left = 0, right = nums.length - 1; // 左闭右闭,left和right都指向可能成为target的元素
if(nums[0] > target || nums[nums.length - 1] < target) return -1;
while(left <= right){ // 左闭右闭情况下,区间左指针和右指针可以相同
int mid = left + ((right - left) >> 1);
if(nums[mid] < target) left = mid + 1;
else if(nums[mid] > target) right = mid - 1; // 右指针要一直保持可能成为target的元素,显然mid不行,所以right = mid - 1
else return mid;
}
return -1;
}
}
接下来是左闭右开的实现方式:
class Solution {
public int search(int[] nums, int target) {
int left = 0, right = nums.length; // 左闭右开,right指针一直指向不可能成为target的下标
if(nums[0] > target || nums[nums.length - 1] < target) return -1;
while(left < right){ // right指针永远指向不可能成为target的元素的下标,和left不可能相等
int mid = left + ((right - left) >> 1);
if(nums[mid] < target) left = mid + 1;
else if(nums[mid] > target) right = mid; // right指针不可能成为target的下标,所以right = mid;不需要-1
else return mid;
}
return -1;
}
}
27.移除元素
这里循环并没有用到fast指针,所以只使用了一个slow指针,一边用于记录数据更新到哪个下标了,还可以记录一共有多少个非val的元素。
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0;
for(int n : nums){
if(n != val){
nums[slow] = n;
slow++;
}
}
return slow;
}
}