代码随想录算法训练营第一天|704. 二分查找、27. 移除元素

450 阅读1分钟

二分查找

二分查找的细节问题:

  1. while(lo<hi) or while(lo<=hi)
  2. lo=mid+1/hi=mid-1 or lo=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;
    }
}