leetcode-80-删除排序数组中的重复项 II

Posted chenjx85

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode-80-删除排序数组中的重复项 II相关的知识,希望对你有一定的参考价值。

题目描述:

给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。

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

示例 1:

给定 nums = [1,1,1,2,2,3],

函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。

你不需要考虑数组中超出新长度后面的元素。

示例 2:

给定 nums = [0,0,1,1,1,1,2,3,3],

函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。

你不需要考虑数组中超出新长度后面的元素。

 

要完成的函数:

int removeDuplicates(vector<int>& nums) 

 

说明:

1、这道题给定一个vector,里面存放着升序排列的int型整数。

这些整数可能有多个,比如[1,1,1,2,2,3,4,5,5,5,5,5],要求每个整数只能出现2次,所以最终变成[1,1,2,2,3,4,5,5]。

为此你需要原地修改vector的数值,要求只能使用O(1)的空间。

最后返回新的vector的长度,不需要返回修改完的vector,但是vector要原地修改完成。

不需要在意修改完的vector后面的元素,测试样例在测试时只会在意你返回的长度以内的vector元素。

 

2、这道题从思路上来说,一点也不难,只是比较繁琐。

我们看一下举的这个例子,[1,1,1,2,2,2,3,3,3]

我们需要先找到第一个可以被替换的位置,第三个1,也就是位置是2。

然后找到第一个需要更换的位置,第一个2,也就是位置是3。

把第一个2放在第三个1那里。

接着继续往后面走,继续匹配。第二个2要放在第一个2的位置上,接着第三个2由于已经出现了两次了,所以不理。

到达下一个不一样的元素3,把3放在第二个2的位置上,把第二个3放在第三个2的位置上,最后的第三个3就不理了。

思路一点都不复杂,代码如下:(附详解)

    int removeDuplicates(vector<int>& nums) 
    {
        int i=1,j=0,s1=nums.size(),count=1,t;
        if(s1==0)return 0;//如果vector中没有元素,返回0,不用修改vector
        else if(s1==1)return 1;//如果vector中只有1个元素,返回1,不用修改vector
        while(i<s1)//找到第一个可以被替换的位置,也就是出现了2次以上的元素
        {
            if(nums[i]==nums[i-1])//count初始值为1
            {
                count++;
                if(count>2)//出现了第三次,那么break,当前i的位置就是第一个可以被后面元素替换的位置
                    break;
                i++;
            }
            else//如果不一样了,那么重新初始化count为1
            {
                i++;
                count=1;
            }
        }
        j=i+1;//要找到第一个需要替换的元素位置
        if(i==s1)return i;//边界条件,比如[1,2,3,4],i==s1,那么直接返回i
        if(j==s1)return i;//边界条件,比如[1,1,1],i=2,j=3,j==s1,那么直接返回i
        while(nums[j]==nums[i]&&j<s1)//j还没超出vector的长度,找到第一个不等于nums[i]的元素位置
            j++;
        if(j==s1)return i;//边界条件,如果j==s1都没有找到不等于nums[i]的,那么返回i
        t=nums[j],count=1;//找到了nums[j]!=nums[i],记录下nums[j]的值,初始化count为1
        nums[i]=nums[j];//修改元素的值
        i++;//到达下一位,i记录的是可以被替换的位置
        j++;//到达下一位,j记录的是需要替换的位置
        while(j<s1)
        {
            if(nums[j]==t)
            {
                count++;
                if(count>2)//如果出现了2次以上,那么我们需要找到跟t不一样的元素值的位置
                {
                    while(nums[j]==t&&j<s1)
                    {
                        j++;
                    }
                    if(j==s1)break;//边界条件,如果没找到,那么break,完全不需要修改vector了
                    t=nums[j];//找到了跟t不一样的元素值,那么更新t
                    nums[i]=nums[j];//修改元素值
                    count=1;//初始化count
                    i++;//i走到下一位
                    j++;//j走到下一位
                }
                else//只出现了2次,那么修改当前nums[i]为nums[j]的值
                {
                    nums[i]=nums[j];
                    i++;
                    j++;
                }
            }
            else//如果跟t不一样,那么修改元素值,更新t值,初始化count
            {
                nums[i]=nums[j];
                count=1;
                t=nums[j];
                i++;
                j++;
            }
        }
        return i;//最后需要返回长度,也就是从0到i的前一位,那么长度为i
    }

上述代码实测12ms,beats 99.85% of cpp submissions。

这道题其实思路很简单,就是琐碎了点,需要测试各种边界条件。

以上是关于leetcode-80-删除排序数组中的重复项 II的主要内容,如果未能解决你的问题,请参考以下文章

leetcode-80-删除排序数组中的重复项 II

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

LeetCode 80. 删除排序数组中的重复项 II(Remove Duplicates from Sorted Array II)

leetcode 80. 删除排序数组中的重复项 II(Remove Duplicates from Sorted Array II)

LeetCode 80. 删除有序数组中的重复项 II 双指针

Python描述 LeetCode 80. 删除有序数组中的重复项 II