代码随想录算法训练营Day 1|LeetCode704 二分查找、Leetcode35 搜索插入位置、Leetcode34 在排序数组中查找元素的第一个和最后一个位置、LeetCode27 移除元素

本文介绍了LeetCode中的四个问题,包括二分查找、搜索插入位置、在排序数组中查找元素的第一个和最后一个位置以及移除元素。这些题目都是基于二分查找算法的扩展,涉及时间复杂度和空间复杂度分析。

 LeetCode704 二分查找

题目链接 : 二分查找

思路

本题较为基础,设置left和right作为数组nums的左右边界,在left<=right条件下循环,令mid=(left+right)/2,循环比较num[mid]与target:①若存在num[mid]==target,则直接return mid;②若num[mid]<target,则说明target应在mid右侧,令left=mid+1,继续循环;③若num[mid]>target,则说明target应在mid左侧,令right=mid-1,继续循环;④若直到left>right,即退出while循环后还未找到target,则说明nums[]数组中没有该元素,return -1.

代码

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left=0;                  //左边界
        int right=nums.size()-1;     //右边界
        while (left<=right)          //循环二分
        {
           int mid=(left+right)/2; 
           if(nums[mid]==target)
            return mid;
           else if(nums[mid]<target) //target在mid右侧
            left=mid+1;
           else                      //target在mid左侧
            right=mid-1;
        }
        
        return -1;   
        }
};

复杂度 

时间复杂度 O(logn)

空间复杂度O(1)

Leetcode35 搜索插入位置

题目链接:搜索插入位置

思路

本题同上题思路基本相同,不再赘述。区别在于当while循环结束还未找到target,此时right+1==left,而插入位置即left.

代码

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

复杂度

时间复杂度 O(logn)

空间复杂度O(1)

Leetcode34 在排序数组中查找元素的第一个和最后一个位置

题目链接:在排序数组中查找元素的第一个和最后一个位置

思路

34、35都还是二分查找的拓展练习,思路上还是大致一样的,但是本题用到了vector,STL容器本人还是比较生疏,回顾了一下才算会用,但使用起来还是比较笨拙,代码执行时间较久。

代码

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        if(nums.size() == 0) 
            return {-1,-1};
        int left =0;
        int right=nums.size()-1;
        vector<int> result={-1,-1};
        while(left<=right){
            int mid=(left+right)/2;
            if(nums[mid]==target){
                result.erase(result.begin(),result.end()); 
                //左边界
                while(mid>0&&nums[mid]==nums[mid-1]) mid--;
                result.push_back(mid); 
                //右边界
                while(mid<nums.size()-1&&nums[mid]==nums[mid+1]) mid++;
                result.push_back(mid);
                return result;
            }
            else if(nums[mid]<target)
                left=mid+1;
            else
                right=mid-1;
        }
        return result;
    }
};

复杂度

时间复杂度 O(logn)

空间复杂度O(1)

LeetCode27 移除元素

题目链接:移除元素

思路

本题比较基础,作为刚经历408的考生也是比较熟悉相关操作。设置len记录数组nums[]的逻辑长度,removelen记录数组需要向前覆盖的距离,并循环遍历nums数组:①若nums[i]==val,则令++removelen,并将逻辑长度len-1;②nums[i]!=val,则将该元素向前覆盖removelen个距离。最后返回nums数组的逻辑长度。

代码

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int len=nums.size();      //记录实际长度
        int removelen=0;          //记录需要前移的元素数
        for(int i=0;i<nums.size();i++){ 
            if(nums[i]==val){     //若num[i]等于val,则令removelen自增,以便于向前覆盖
                ++removelen;
                --len;            //实际长度减一
            }           
            else if(nums[i]!=val){
                 nums[i-removelen]=nums[i];
            }                  //非val元素向前覆盖
               
        }
        return len;
    }
};

复杂度

时间复杂度 O(n)

空间复杂度O(1)

总结

今天第一天,因为时间比较赶,题目也比较基础,就没咋看卡哥的视频和资料,直接就做题了,也是在找找状态的同时复习一些基础知识了,关于卡哥讲到的二分法区间闭开问题等等理论知识明天找时间补上。自己写代码的时候还是有些生硬,觉得有些小问题,比如34题的执行时间、27题数组逻辑长度后面的空间未释放等等,明天继续努力。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值