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

LeetCode704二分查找

题目链接二分查找

思路:

二分查找首先要求在一个有序的数组中才能进行,然后取位于数组中间的值与目标数target作比较,若目标值大于中间值则下一次比较在区间右侧,反之左侧。二分查找中重要的地方在于区间的选取,是左右两边均为闭区间还是一个左闭右开的区间。

闭区间:

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

    }
};

如果在循环时写成了left<right,就会有测试样例不通过,如果left=right,区间仍然是有效的。

左闭右开:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size(); // 定义target在左闭右开的区间里,即:[left, right)
        while (left < right) { // 因为left == right的时候,在[left, right)是无效的空间,所以使用 <
            int middle = left + ((right - left) >> 1);
            if (nums[middle] > target) {
                right = middle; // target 在左区间,在[left, middle)中
            } else if (nums[middle] < target) {
                left = middle + 1; // target 在右区间,在[middle + 1, right)中
            } else { // nums[middle] == target
                return middle; // 数组中找到目标值,直接返回下标
            }
        }
        // 未找到目标值
        return -1;
    }
};

LeetCode27移除元素

移除元素

思路:数组中由于数据的存放是连续的,所以删除元素时需要将右侧的所有元素向左移动一位。

暴力破解法:

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int size=nums.size();
        for(int i=0;i<size;i++){
            if(nums[i]==val)
            {
              for(int j=i+1;j<size;j++)
              {nums[j-1]=nums[j];}
              i--;//下标i以后的数据全都向左移动了一位所以i也需要左移一位
              size--;//数组长度减一
            }
        }
        return size;
    }
};

快慢指针法:

快慢指针法是定义两个指针

  • 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
  • 慢指针:指向更新 新数组下标的位置
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int size=nums.size();
        int slowindex=0;
        for(int fastindex=0;fastindex<size;fastindex++)
        {
            if(val!=nums[fastindex]){
                nums[slowindex++]=nums[fastindex];
            }
        }
        
        return slowindex;
    }
};

相对快慢指针:

基于元素顺序可以改变的题目条件,得出移动元素最少的方案

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int slowindex=0;
        int fastindex=nums.size()-1;
        while(slowindex<=fastindex)
        {
            while(slowindex<=fastindex && nums[slowindex]!=val){
                ++slowindex;
            }//从左边找和val相同的元素
            while(slowindex<=fastindex && nums[fastindex]==val){
                --fastindex;
            }//从右边找与val不同的元素
            if(slowindex < fastindex){
                nums[slowindex++] =nums[fastindex--];
            }//将右边的元素放到左边

        }
        
        return slowindex;//慢指针会指向下一个元素
    }
};

总结:

今天主要学习了二分查找和数组中元素移除,二分查找中重点在于区间的选取,左闭右闭和左闭右开在循环判断条件上是不同的;而元素移除重点在于快慢指针的应用和理解。快指针是用来查找下一个新数组中的元素,慢指针是用来标出下一个元素的下标。

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值