代码随想录Day1打卡 二分查找+双指针

57 阅读1分钟

704. 二分查找

二分查找的一般写法有左闭右闭左闭右开。而区分这两种写法的一般是看右指针所指是否是包含在区间内的,即【letf, right】 还是 【left, right)。而由于区间的范围不同,也会影响在收缩边界时right和left的赋值。 左闭右闭写法:

var search = function(nums, target) {
    // 区别点一: 因为右指针在区间内,所以我们从最后一个index开始
    let left = 0, right = nums.length - 1;
    // 区别点二:因为我们是从nums.length - 1开始为右节点,类比(i = 0; i <= nums.length - 1; i++) 
    while (left <= right) {
        let mid = left + Math.floor((right - left)/2);
        if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            // 区别点三:因为我们排除了mid不是target,所以【left,mid-1】是下一个搜索范围
            right = mid - 1; 
        } else {
            return mid;
        }
    }
    return -1;
};

左闭右开写法:

var search = function(nums, target) {
    // 区别点一:因为右指针是右边界,所以我们从length开始
    let left = 0, right = nums.length;
    // 区别点二:因为我们是从nums.length开始为右边界,类比(i = 0; i < nums.length - 1; i++)
    while (left < right) {
        let mid = left + Math.floor((right - left)/2);
        if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            // 区别点三:因为我们排除了mid是不可能为target的,所以target在【left,mid)中间,收缩右边界。
            right = mid; 
        } else {
            return mid;
        }
    }
    return -1;
};

27. 移除元素

我们可以用双指针的技巧来实现O(n)的时间复杂度:

var removeElement = function(nums, val) {
    let read = 0, write = 0
    // 因为read永远比write走得快,所以我们可以直接检查read然后赋值给write
    while (read < nums.length) {
        if (nums[read] !== val) {
            nums[write] = nums[read]
            write += 1
        }
        read += 1
    }
    return write
};