二分法,双指针

230 阅读1分钟

二分法

[题目](704. Binary Search - 力扣(Leetcode))

易错点

1.while循环中的判断,是小于还是小于等于
while(left < right) or while(left <= right)
2.更新区间,是 right = middle 还是 right = middle - 1
主要还是边界值难以确定,容易导致出现问题

循环不变量

区间:左闭右闭和左闭右开
在写二分法的时候,要坚持区间的不变量,才能不写乱边界

左闭右闭写法

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size() - 1;
        while(left <= right) {
            int middle = left + (right - left) / 2;
            if (nums[middle] > target) {
                // 因为是左闭右闭,所以不能包含middle
                // 如果是middle,则下次循环就会包含middle,但是当前的判断已经是middle大于target了
                right = middle - 1;
            }
            else if (nums[middle] < target) {
                left = middle + 1;
            }
            else {
                return middle;
            }
        }
        return -1;
    }
};

左闭右开写法

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size();
        while(left < right) {
            int middle = left + (right - left) / 2;
            if (nums[middle] > target) {
                right = middle;
            }
            else if (nums[middle] < target) {
                left = middle + 1;
            }
            else {
                return middle;
            }
        }
        return -1;
    }
};

双指针

[题目](27. 移除元素 - 力扣(Leetcode))

理论基础

数组实际是无法删除,只能通过覆盖达到删除的效果

双指针思路

双指针能够使用一层for循环就能解决

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        // 定义快慢指针
        int slowIndex = 0;
        for (int fastIndex = 0; fastIndex < nums.size(); fastIndex++) {
            if (val != nums[fastIndex]) {
                nums[slowIndex] = nums[fastIndex];
                slowIndex++;
            }
        }
        return slowIndex;
    }
};