数组专题---删除重复项、删除指定元素

27. 移除元素

双指针法(前后指针)

vector容器是顺序存储,所以不能单独删除数组中某个元素,只能覆盖!

因为要求“原地”删除,所以想要用“双指针法”

自己的双指针思路是:

  • 定义两个指针,分别指向数组的头尾

  • first负责定位到val的位置,last负责定位到非val的位置,然后把非val和val交换,最终使所有val都聚在数组后面,再调用erase删除所有val

  • 两个指针指向的情况如下

    *first*lastoperation
    =val=vallast–
    =val!=valfirst++,last–
    !=val!=valfirst++
    !=val=valfirst++,last–

过程中忽略了以下几个细节

  • 数组为空的情况!

  • 数组长度为1时可以直接返回结果,会更快

  • 数组长度为2时也有四种情况,直接判断,返回结果,会更快

AC代码

//时间复杂度:O(N)
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        if(nums.size()==0)
            return 0;
        if(nums.size()==1)
            return nums[0]==val?0:1;
        if(nums.size()==2)
        {
            if(nums[0]==val&&nums[1]==val)
                return 0;
            if(nums[0]==val)
                {nums[0]=nums[1];return 1;}
            if(nums[1]==val)
                return 1;
            return 2;
        }
        vector<int>::iterator first=nums.begin();
        vector<int>::iterator last=nums.end();
        last--;
        while(first<last)
        {
            if(*first==val&&*last!=val)
            {
                int temp=*first;
                *first=*last;
                *last=temp;
                first++;last--;
            }
            else if(*first!=val&&*last==val)
                first++,last--;
            else if(*first==val&&*last==val)
                last--;
            else
                first++;
            
        }
        if(*first==val)
            nums.erase(first,nums.end());
        else
            nums.erase(++first,nums.end());
        
        return nums.size();
    }
};

看到官方题解,才知道自己的思路是对的,但是写的太复杂了!

优化代码:

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

双指针法(快慢指针)

看到网上的题解,用的是“快慢指针法”

思路

  • 定义快慢指针
  • slow指向要被覆盖的位置,fast指向下一个位置
  • 如果slow指向的元素值是val,则fast右移一个位置,并用其元素值覆盖slow
  • 如果slow指向的元素值不是val,则slow,fast都右移
//时间复杂度:O(N)
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int len = nums.size();
        int slow= 0;
        for (int fast = 0; fast< n; fast++) {
            if(nums[slow]!=val)
            	nums[slow++]=nums[fast];
        }
        return left;
    }
};

因为题目说元素顺序可以改变,所以,可以考虑先对数组排序,再用slow定位到第一个val,fast定位到最后一个val的下一个位置,然后把后面的元素覆盖掉所有Val

具体代码。。以后再写吧

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值