代码随想录算法训练营D1

本文讨论了二分查找算法的递归和迭代实现,强调了左闭右开/左闭右闭的区别,并介绍了移除元素问题中暴力解法、双指针法(包括常规和相向)的使用,提醒读者注意数组操作中的边界条件和场景选择。
摘要由CSDN通过智能技术生成

D1: 为什么报这个群呢,之前一直很难坚持,我觉得还是报个群,然后大家一起写,一起打卡会坚持住。没有自制力,再没有一起写的朋友的话,真的可以躺平了-.-

704.Binary Search:题目还是很简单的,二分查找,属于是自己写会写,但是会有小细节漏下。重点是左闭右开还是左闭右闭。详细见下

//递归写法
class Solution {
public:
    int search(vector<int>& nums, int target,int low,int high) {
        if(low>high) return -1;
        int mid=low+(high-low)/2;
        if(nums[mid]==target) return mid;
        if(nums[mid]>target) {
            high=mid-1;
            return search(nums, target, low, high);
        }else{
            low=mid+1;
            return search(nums, target, low, high);
        }
    }
};

递归写法,先确定确定递归函数,返回值以及参数,然后确定递归终止条件,如果是左闭右开,就要改成

if(low>=high) return -1;

最后是单层递归的逻辑,也就是target在哪边查哪边。

下面是迭代法:

//迭代法
class Solution {
public:
    int search(vector<int>& nums, int target) {
        if(nums.empty()) return -1;
        
        int low=0;
        int high=nums.size()-1;
        
        while(low<=high){
            int mid=low+(high-low)/2;
            if(nums[mid]==target) return mid;
            else if(nums[mid]>target){
                high=mid-1;
            }else{
                low=mid+1;
            }
        }
        return -1;
    }
};

左闭右闭写法的话,[low,high]是有效的,所以while后面是可以low<=high的,如果是左闭右开,就不能<=了,因为[low,high)无效。相应的,下面的low和high也要对应-1,+1。

27. Remove Element
暴力解法:

// 时间复杂度:O(n^2)
// 空间复杂度:O(1)
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--; 
                size--; 
            }
        }
        return size;

    }
};

然后是双指针法,快指针指向整个数组,慢指针记录新数组的长度。

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

看了代码随想录的文章后,还有一种相向双指针法,改变了元素相对位置,确保了移动最少元素。

    int removeElement(vector<int>& nums, int val) {
        int slow=0;
        int fast=nums.size()-1;
        while(slow<=fast){
            while(slow<=fast && nums[slow]!=val){
                ++slow;
            }
            while(slow<=fast && nums[fast]==val){
                --fast;
            }
            
            if (slow < fast) {
                nums[slow++] = nums[fast--];
            }
        }
        return slow;
    }

总结:双指针法的使用要强化一下,然后对于适用场景,比如数组场景要更加熟悉;数组使用时的边界条件要多加判断。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值