LeetCode经典面试150题-80题

80. 删除有序数组中的重复项 II

题目描述:

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

题解: 

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int count=1;
        int ptr=0;
        for(int i=1;i<nums.size();i++){
            if(nums[i]!=nums[ptr]){
                ptr++;
                nums[ptr]=nums[i];
                count=1;
            }
            else if(count==1){
                    count++;
                    ptr++;
                    nums[ptr]=nums[i];
            }
        }
        return ptr+1;
    }
};
解题思路 :

遍历一遍有序数组,记录相同数值的元素个数,若个数>=2,则跳过,反之则保留。

注意点:

题目要求:原地

原地算法in-place algorithm)是一种使用小的,固定数量的额外之空间来转换资料的算法。当算法执行时,输入的资料通常会被要输出的部分覆盖掉。

简单来说就是不使用其他备用数组,在原数组基础上做变动。

回看前几次做题也遇到了要求原地,不过当时没注意,因此这也是一个出错点。

优化解法:
class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
      int n=nums.size();
      if(n<=2){
        return n;
      }
      int slow=2;
      int fast=2;
      while(fast<n){
        if(nums[slow-2]!=nums[fast]){
            nums[slow]=nums[fast];
            slow++;
        }
        fast++;
        }
        return slow;
    }
};

这种方法官方叫做双指针解法,利用数组的有序性,比较当前元素和前两位的元素的值,如若相等,则跳过,若大于,则保留。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值