代码随想录day1--二分查找,移除元素

leetcode704.二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 

示例 1:

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

示例 2:

输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

解这道题,首先需要确定的是区间。区间就是你需要遍历的范围

我们一般使用以下两种区间

        左闭右闭[left,right]

        左闭右开[left,right)

之后,有很多人在做二分查找题目时会有两个疑问:

第一:while循环的条件是什么是while(left<right)还是while(left<=right)

第二:一次查找结束后,mid是应该mid-1/mid+1又或者是让right=mid/left=mid

由这两个问题,可以引出两个解法,也会就是上面所说的左闭右闭,左闭右开

左闭右闭代码如下

int search(vector<int>& nums, int target) {
        int left = 0,right = nums.size()-1;
        while(left <= right){//使用=是因为可以遍历最右边的数据
            int mid = (left+right)/2;
            if(target < nums[mid]){
                right = mid-1;//使用mid-1是因为,mid已经被遍历,不是需要的数据,所以使用mid-1
            }
            else if(target > nums[mid]){
                left = mid+1;//同上
            }else return mid;
        }
        return -1;
    }

 左闭右开代码如下

int search(vector<int>& nums, int target) {
        int left = 0,right = nums.size();//因为右边为开区间,不会遍历最右边的元素,所以不用减一
        while(left < right){//因为不遍历最右边的元素,并且需要判断,所以mid不减一
            int mid = (left+right)/2;
            if(target < nums[mid]){
                right = mid;
            }
            else if(target > nums[mid]){
                left = mid+1;
            }else return mid;
        }
        return -1;
    }

LeetCode27.移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

这道题可以使用暴力解法进行求解,使用双层for循环即可。第一层循环遍历所有元素,在找到需要移除的元素后,进行第二层遍历,进行移除操作。再将之后的元素都依次向前移动即可。

暴力求解代码如下

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--;
                size--;
            }
        }
        return size;
    }

使用暴力求解的时间复杂度是O(N^2),可以引入双指针的思想进行求解

我们定义两个指针,一个快指针,一个慢指针

快指针fastPoint:用于确定新数组的元素值,也就是不等于目标元素的数组元素

慢指针slowPoint:用于确定心数组的下标位置。。

明白了双指针的作业,我们就将快指针指向的元素加入到慢指针指向1元素下标中即可。

双指针代码如下

int removeElement(vector<int>& nums, int val) {
        int fastPoint=0;//用于获取新数组中的元素,即在arr中不等于val的数组元素
        int slowPoint=0;//用于确定新数组1下标值,即在快指针获取到元素后应放在新数组的哪个下标


        for(;fastPoint<nums.size();fastPoint++){
            if(nums[fastPoint] != val){
                nums[slowPoint] = nums[fastPoint];
                slowPoint++;
                }
            }
        return slowPoint;
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值