原题链接:704 二分查找
二分查找:左闭右闭和左闭右开两种写法
一:左闭右闭
class Solution {
public int search(int[] nums, int target) {
int l = 0, r = nums.length - 1;
while (l <= r) {
int mid = (r - l) / 2 + l;
if (nums[mid] == target) return mid;
else if (nums[mid] < target) l = mid + 1;
else r = mid - 1;
}
return -1;
}
}
二:左闭右开
class Solution {
public int search(int[] nums, int target) {
int l = 0, r = nums.length;
while (l < r) {
int mid = (r - l) / 2 + l;
if (nums[mid] == target) return mid;
else if (nums[mid] < target) l = mid + 1;
else r = mid;
}
return -1;
}
}
注意到两种写法的差异点:首先是while()中一个需要用<=,另一个则是<,这是由于左闭右闭的写法中,左右区间端点都是可以被取到的而有意义的,因此需要用<=,而左闭右开写法则由于最开始的右端点r=nums.length,是取不到的位置,因此用<;
另一个差异点在于if(nums[mid] > target)时对r的重新赋值。左闭右闭写法中r = mid - 1,因为这个nums[mid]一定不是要查找的target,接下来要查找的位置就是mid - 1;左闭右开写法中r = mid,因其右端点为开区间写法,不会被取到,因此赋值为r = mid。
原题链接:27 移除元素
本题的暴力解法为:外层循环找等于val的值,内层循环将这个等于val的值后面的数组元素覆写过来。
巧妙解法为双指针法(快慢指针法):
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];
}
return slow;
}
}
其思想为定义快慢指针为:
- 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
- 慢指针:指向更新 新数组下标的位置