704. 二分查找、27. 移除元素

704. 二分查找、27. 移除元素

704.二分查找

题目链接

文章讲解

视频讲解

重点:要注意是自己定义区间的是左闭右开,还是左闭右闭

左闭右开的二分查找

耗时 0:6:11

//时间复杂度:O(log n)
//空间复杂度:O(1)
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int len = nums.size();
        int left = 0, right = len;
        int mid;
        while(left < right) //取到right无意义,所以没有等于
        {
            mid = (left + right) / 2;
            if(nums[mid]==target)
                return mid;
            else if(target < nums[mid])//目标值在左半区           
                right = mid;
            else
                left = mid+1;//目标值在左半区 
        }
        return -1;
    }
};

左闭右闭

//时间复杂度:O(log n)
//空间复杂度:O(1)
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int len = nums.size();
        int left = 0, right = len - 1;
        int mid;
        while(left <= right)// 取到right有意义,所以有等于
        {
            mid = (left + right) / 2;
            if(nums[mid]==target)
                return mid;
            else if(target < nums[mid])//目标值在左半区           
                right = mid-1;
            else
                left = mid+1;//目标值在左半区 
        }
        return -1;
    }
};

27.移除元素

题目链接

文章讲解

视频讲解

第一眼想法:暴力解

耗时 0:5:21

暴力解示意图

  • 循环列表,遇到目标值就删除(把整个后面的数组前移)
  • 注意每一次执行玩后移操作后,i要减1。因为如果后面一个元素也是目标值的话,就会漏掉它。
// 时间复杂度:O(n^2)
// 空间复杂度:O(1)
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int len = nums.size();
        for (int i = 0; i < len;i++)
        {
            if(nums[i]==val)
            {
                len--;
                for (int j = i; j < len;j++){
                    nums[j] = nums[j + 1];
                }
                i--;
            }
           
        }
        return len;
    }
};

看完文档思路:快慢指针
遇到列表问题要经常考虑双指针解法。
耗时 0:25:34

快慢指针示意图

  • 快指针遇到目标值就跳过,目的是指向非目标值,便于覆盖慢指针上的元素。
  • 当快指针遇到目标值的回合,慢指针不会移动,目的是指向待处理的元素。
  • 当快指针指向非目标值,而慢指针又慢于快指针时,说明该执行覆盖操作。
// 时间复杂度:O(n)
// 空间复杂度:O(1)
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int slow = 0, fast = 0;
        int len = nums.size();
        while(slow < len)
        {
            if(nums[fast] == val)
            {
                fast++;
                len--;
            }
            else if(slow < fast)
            {
                nums[slow] = nums[fast];
                slow++;
                fast++;
            }
            else
            {
                fast++;
                slow++;
            }
        }
        return len;
    }
};

看完答案:发现后面两个判断可以归为一类

// 时间复杂度:O(n)
// 空间复杂度:O(1)
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int slow = 0, fast = 0;
        int len = nums.size();
        while(slow<len)
        {
            if(nums[fast]==val)
            {
                fast++;
                len--;
            }
            else
            {
                nums[slow] = nums[fast];
                fast++;
                slow++;
            }
        }
        return len;
    }
};
  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值