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

LeetCode 704.二分查找

题目描述:升序数组nums中查找target,找到返回下标,找不到返回-1

  • 掌握左闭右闭左闭右开两种区间规则的二分写法

视频讲解https://www.bilibili.com/video/BV1fA4y1o715

文章讲解https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html

笔记整理:

        1. 左闭右闭

        即在区间 [left, right] 中进行查找

        区间有效对应:while (left <= right)

        如图所示,阴影表示待查找元素,更新的变量以红色标出。​​​​

左闭右闭

        若nums[middle]大了,往左半边找,即 [left, middle - 1]

        若nums[middle]小了,往右半边找,即 [middle + 1, right]

        2. 左闭右开

        即在区间 [left, right) 中进行查找

        区间有效对应:while (left < right)

左闭右开

        若nums[middle]大了,往左半边找,即 [left, middle)

        若nums[middle]小了,往右半边找,即 [middle + 1, right)

LeetCode 27. 移除元素

题目描述:数组nums中原地移除值为val的元素,返回新数组长度

  • 暴力解法:两层for循环,每遇到一个val,进内层循环将其后元素逐个向前覆盖
  • 双指针法:
    • 同向:
      • 均从左往右,不改变元素相对位置
      • 一层for循环,快指针扫整个数组,遇到不为val的就赋给慢指针
    • 相向
      • 会改变元素相对位置,移动最少元素
      • left从左边起步,找val元素;right从右边起步,找非val元素赋给left位置

视频讲解https://www.bilibili.com/video/BV12A4y1Z7LP

文章讲解https://programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html

笔记整理:

        1.暴力解法:

        需要定义一个变量用于记录数组元素个数,每删一个就--,用于返回值及for循环的结束条件;

        注意覆盖掉i位置元素之后,下一轮外层循环还需扫描i位置,但for里有i++,故需提前i--回退;

        2.双指针法:

        ①同向:

                slow表示新数组下标;

                用fast扫描原数组,寻找用于新数组的值,找到后直接赋给slow位置即可;

                最终slow即为新数组元素个数。

        ②相向:

                left表示新数组下标;

                left遇到用于新数组的值(非val)直接跳过,遇到val停下;

                right遇到val跳过,遇到用于新数组的值(非val)停下;

                若left < right,则将right位置元素赋给left位置,并更新left、right;

                两指针相遇,表示还有最后一个数需处理,故while(left <= right);

                最终left即为新数组元素个数。

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        // 双指针(相向)
        int left = 0;
        int right = nums.size() - 1;
        while (left <= right) {
            // left找val(需要被覆盖的值)
            while (left <= right && nums[left] != val) {
                ++left;
            }
            // right找!val(新数组的值)
            while (left <= right && nums[right] == val) {
                --right;
            }
            if (left < right) {
                nums[left++] = nums[right--];
            }
        }
        return left;
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值