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

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

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

704. 二分查找

代码如下(示例):

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

掌握一种写法:
左闭右闭,定义 target 是在一个在左闭右闭的区间里,也就是[left, right]

区间的定义决定了二分法的代码应,在[left, right]区间,写法如下:

while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=
if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1。

27. 移除元素

代码如下(示例):
双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个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];
            }
        }
        return slowIndex;
    }
};

可以理解为快指针寻找新数组元素并保存,遇到val则跳过,只不过在原数组中保存(利用慢指针)。


相向双指针方法:基于元素顺序可以改变的题目描述改变了元素相对位置,确保了移动最少元素

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int leftIndex = 0;
        int rightIndex = nums.size() - 1;
        while (leftIndex <= rightIndex) {
            // 找左边等于val的元素
            while (leftIndex <= rightIndex && nums[leftIndex] != val){
                ++leftIndex;
            }
            // 找右边不等于val的元素
            while (leftIndex <= rightIndex && nums[rightIndex] == val) {
                -- rightIndex;
            }
            // 将右边不等于val的元素覆盖左边等于val的元素
            if (leftIndex < rightIndex) {
                nums[leftIndex++] = nums[rightIndex--];
            }
        }
        return leftIndex;   // leftIndex一定指向了最终数组末尾的下一个元素
    }
};

可以理解为左边找空箱子,右边找要装的东西给左边,直到左边的空箱子满了(左指针>右指针),下标正好是长度。

总结

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值