二分查找
二分查找的细节问题:
while(lo<hi)orwhile(lo<=hi)lo=mid+1/hi=mid-1orlo=mid/hi=mid
常见的说法是,不同写法代表不同搜索区间的处理方式,同时初始化右端点方式也不相同。不常见的是,搜索区间与代码不对应,例如,寻找左端点模版:
class Solution {
public int search(int[] nums, int target) {
// 搜素区间理解为[lo,hi]
int lo = 0;
int hi = nums.length - 1;
while (lo < hi) {
int mid = lo + hi >>> 1;
// 更改搜素区间:[lo,mid]
// 不能排除mid,由于nums[mid]可能为target
if (nums[mid] >= target) hi = mid;
// 更改搜素区间:[mid+1,hi]
else lo = mid + 1;
}
// 可以假设最后一步[lo,lo+1],a[lo]=target
// 倘若while(lo<=hi),将陷入死循环
return (nums[lo] == target) ? lo : -1;
}
}
移除元素
从过滤器的角度思考,本题只需要遍历一遍数组,检查是否符合条件【不等于目标值】,将符合条件的转存/保留。其中,一边用读指针遍历访问,同时用写指针覆盖更新。人如其名,写指针永远无法领先于访问指针,不仅节省时间,还高效利用空间,无需额外新建数组储存结果。
class Solution {
public int removeElement(int[] nums, int val) {
int write = 0;
for (int read = 0; read < nums.length; read++) {
if (nums[read] != val) {
nums[write++] = nums[read];
}
}
return write;
}
}