2023.2.16 LeetCode代码随想录(Carl哥)跟刷1 数组篇

文章介绍了如何使用二分查找法解决寻找和删除数组元素的问题,强调了边界条件处理和循环实现的重要性。同时,通过比较不同方法,如使用find()函数与双指针策略,展示了在删除有序数组重复项和移动零元素时的效率与简洁性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 二分查找(704)

主要找左右边界,如果左右闭区间的话,更新的边界为Mid-1,左闭右开的话不用建议;参考代码随想录 (programmercarl.com);主要没想到可以直接写while循环,还是不熟悉,硬套的递归二分查找,甚至又写了个函数。

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

参考答案

mid也要更新,所以一定要写进循环里!!!!!

class Solution {
public:  
    int search(vector<int>& nums, int target) {
        int r=nums.size()-1;
        int l=0;      
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(nums[mid]==target)
            return mid;
            else if(nums[mid]>target)
            r=mid-1;
            else
            l=mid+1;
        }
        return -1;
    }
};
  1. 移除元素(27)

自己的方法:调用find()函数进行查找并对其进行删除,find()返回值为迭代器,查找失败则返回最后一个元素的后一位的迭代器即end();注意find()为库函数,不需要用对象调用(nums.find()错错错)。

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        vector<int>::iterator it;
        while(true)
        {
            it=find(nums.begin(),nums.end(),val);
            if(it!=nums.end())//一定要判断一下,否则查找失败时返回end()直接进行删除出错
            nums.erase(it);
            else
            break;
        }
        return nums.size();
    }
};

参考方法:代码随想录 (programmercarl.com)使用快慢指针(双指针法)数组、链表、字符串会用到

快指针:负责向前走,一直指向下一个元素

慢指针:负责停顿在需要被覆盖的元素(需要删除的那个元素)的位置,方便将不需删除的元素移到此处

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int size=nums.size();
        int fp=0,sp=0;
        for(;fp<size;fp++)
        {
            if(nums[fp]!=val)
            {
                nums[sp++]=nums[fp];
            }
        }
        return sp;
    }
};
2.1删除有序数组中的重复项(26)

老笨方法:

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        vector<int>::iterator it=nums.begin();
        while(it!=nums.end())
        {
            int counter=count(nums.begin(),nums.end(),*it);
            if(counter>1)
            {
                nums.erase(it,it+counter-1);
            }
            it++;
        }
        return nums.size();

    }
};

示例代码:双指针

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int size=nums.size();
        int fp=1,sp=1;
        for(;fp<size;fp++)
        {
            if(nums[fp]!=nums[fp-1])
            {
                nums[sp++]=nums[fp];
            }
        }
        return sp;
    }
};
2.2移动零(283)

老方法:

使用[ ]时一定要注意越界问题,不能再没有预留空间的情况下使用nums[ ]进行尾插,只可以使用push_back。

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int oldsize=nums.size();
        vector<int>::iterator it=nums.begin();
        while(true)
        {
            it=find(nums.begin(),nums.end(),0);
            if(it!=nums.end())
            nums.erase(it);
            else
            break;
        } 
        int newsize=nums.size();
        /*int i=0;
        for(i;i<oldsize-newsize;i++)
        nums.push_back(0);*/
        nums.resize(oldsize);
        for(;newsize<oldsize;newsize++)
        nums[newsize]=0;

    }
};

双指针:

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        
        int fp=0,sp=0,size=nums.size();
        for(;fp<size;fp++)
        {
            if(nums[fp]!=0)
            nums[sp++]=nums[fp];
        }
        for(sp;sp<size;sp++)
        {
            nums[sp]=0;
        }

    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值