1. 程式人生 > >leetcode-80-刪除排序數組中的重復項 II

leetcode-80-刪除排序數組中的重復項 II

http eat ons ike urn 不難 題目 mission iss

題目描述:

給定一個排序數組,你需要在原地刪除重復出現的元素,使得每個元素最多出現兩次,返回移除後數組的新長度。

不要使用額外的數組空間,你必須在原地修改輸入數組並在使用 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