数据结构 day1:二分查找、移除元素

day1 二分查找 移除元素


Problem: 704. 二分查找

二分查找

这是一个左闭右闭的二分查找算法,一个数组的大小是N,因为是从0开始。首先需要把这个数组全部放进来,所以放进数组的应该是0~N-1。如果使用左闭右闭,刚刚好是0~N-1,但是如果是左闭右开的话,需要放的是0~N,因为N取不到嘛。

所以,这里分为两种情况:左闭右闭和左闭右开,为什么没有左开右闭,原因很简单,如果要是左开右闭,想放入的数组是0~N-1,那么需要左面为-1,也就是说放进去就是-1~N-1,所以避免-1,就一般不设左开的情况。(这里的开闭其实是表示了容纳数组的一个情况)
以上是你选择的一个方法,也就是你可以选择两种方法来存放你要查找的数组。
接下来就是根据不一样的方法来确定不一样的判断策略:

左闭右闭

如果选择了左闭右闭的方法,意味着arr[0~N-1]全部都是可以直接取得,所以在while循环中,就是while(left <= right),这里的left是0,right是N-1。
再接下来,逻辑还是很简单的,如果目标值比arr[middle]小,那么说明目标值在middle的左边,所以right = middle - 1。因为这里是右闭,所以右面的这个始终是可以取到的,所以你判断的有效内容就应该是(0~middle-1),因为middle一定不符合,同理如果目标值比arr[middle]大,那么就去右边,因为左闭,所以也是(left+1~right)。

Code


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

    }
};

左闭右开

左闭右开其实只有一点点区别,就是它放的有效区间的表示不一样了,为什么叫有效区间的表示呢?举个例子:
你要放入的区间是0~N-1
使用左闭右闭:[0,N-1]
使用左闭右开:[0,N)
有效区间一样,但是只是表示的不一样。
所以while(left < right),这里left是0,right是N,那能取到arr[N]吗?,明显取不到。
接下来是比较那里,其实和上面是类似的,如果target大于middle的话,和上面一样,因为左边是闭的,如果target小于middle的话,那个right = middle;不需要-1就可以了,因为你的middle肯定不满足,目的是不取它,然而你刚刚的while判断,刚好右开,所以完美的不取middle,所以也不用-1。

最后还有一点要注意, int left = 0,right = nums.size();这里right不是N-1
而是N,注意要改一下!

Code


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

    }
};

移除元素

Problem: 27. 移除元素

快慢指针删除数组元素

使用了快慢指针,这个主要是要知道数组中的删除其实是覆盖,也就是说只要是连续的覆盖,都可以使用快慢指针的方法来解决。

解题方法

使用快指针来遍历整个数组,然后把要删除的目标值跳过,即可。
跳过的方法也很简单:
if(num[fast] != val),这样就可以避开要删除的目标值,里面是你想做的,在这里,目标操作是要把要删除的目标值略过去,所以只需要让快指针遍历的时候,如果不是目标值,那就覆盖即可,覆盖完slow移到下一位,等待下一次的覆盖。

Code

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int fast = 0,slow = 0;
        for(fast = 0;fast < nums.size();fast++)
        {
            if(nums[fast] != val)
            {
                nums[slow] = nums[fast];
                slow++;
            }
        }
        return slow;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你牌打得好

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值