算法训练营第一天 /力扣:704 二分查找 、27 移除数组元素

**

1.二分查找

**
前提:有序数组

思路:不断缩小区间直到找到所需的元素

KEY:坚持循环不变量的原则,我是通过左闭右开的方式实现的二分查找,因此在查找的过程中就需要一直坚持这样的定义方式,既然是左闭右开,那么也就意味着左边和右边的边界是不可以相等的,否则这就是一个不合法的区间,例如[1,1),因而在设置循环条件的时候,left必须小于right才可以;同理,当后面进行元素的比较时并更新边界的时候,也要遵循该原则才可以

总结:
一定要根据区间的定义方式来决定边界的处理;
凡是有序数组都可以考虑二分查找,它的时间复杂度只有O(logn)。

代码:

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

2.移除数组元素

思路:数组的删除本质是覆盖,因此覆盖的操作是不能省的,这也决定了该操作的时间复杂度不可能低于0(n)
本题可以通过暴力方式解,就是写两层for循环,第一层查找删除的元素,第二层实现覆盖,但是这样的时间复杂度平均会达到O(n^2)的水平
通过双指针的方式可以实现O(n)的时间复杂度,fast用来指向新数组的元素(也就是不等于待删元素的元素),slow用来指向新数组的下标

KEY:fast不等于待删除元素的时候,就把该元素赋值给新数组的下标所指向的位置,并让slow++,这样当fast遍历完数组时,新数组也就构建完成了,slow的值就是新数组的大小,因为数组的下标是从0开始的。

总结:双指针是用fast通过遍历的方式来完成查找,将不用删的元素配合slow直接完成覆盖,因此时间复杂度只有O(n)。

代码:

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
          //双指针         
          int slow=0;
          for(int fast=0;fast<nums.size();fast++)
        {
              if(nums[fast]!=val)
            {
               nums[slow]=nums[fast];//把新数组元素放到新数组下标所对应的位置
               slow++;
            }
        }
        return slow;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值