[LeetCode]problem 80. Remove Duplicates from Sorted Array II

原创 2016年06月02日 00:39:29

link

TAG

双指针

思维方式

容器的end()调用耗时显著性

方法

算是很容易想到的题,然而写起来却很纠结…还得多练啊..

我的思路是,记录重复的次数,初始为0,如果相等一次,则首先+1,然后判断是否小于2,如果是,则继续移动双指针并赋值;如果否,则只需移动遍历指针即可。如果不等,则清零重复次数,移动双指针并赋值。

纠结的问题有:

  1. 遍历指针从哪里开始?

    uniq指针不得不从第一个开始,那么遍历指针如果从第一个开始,那么上述过程就不对了。

    我们需要明确的就是,uniq指针在上述逻辑表示指向uniq结果的最后一个位置。所以,根据此定义,其实遍历指针必须从第2个位置开始(表示第一个位置以及是uniq的)!自己的纠结是逻辑不清导致的。

  2. 输入限制

    上述逻辑不能处理输入为空的情况!

    这是因为此逻辑成立的条件就是数组非空!因为uniq表示uniq部分的最后一个位置,如果数组未空,那么根本不存在uniq部分。

以上的方法很多条件判断。

完成上述代码后,看了DISCUSS,第一个HOT的答案真是让人难以置信!原来可以如此简洁与简单!

我把代码贴过来吧:

int removeDuplicates(vector<int>& nums) {
    int i = 0;
    for (int n : nums)
        if (i < 2 || n > nums[i-2])
            nums[i++] = n;
    return i;
}

我将其改写为等价的如下代码:

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        size_t sz = nums.size() ;
        if(sz < 3) { return sz ;}
        size_t rear_pos = 1 ; 
        for(size_t pos = 2; pos < sz ; ++pos)
        {
            if(nums[pos] != nums[rear_pos-1])
            {
                nums[++rear_pos] = nums[pos];
            }
        }
        return rear_pos + 1 ;
    }
};

核心就是——不需要要记录有多少重复的数字,只需判断已有结果的状态!如果当前遍历指针的值与当前uniq指针(uniq部分的尾位置)的前一个位置的值相等(代码中是大于关系,其实可以改为不等于),那么就必然有:结果中已经有两个数相同了。

这其实是两种思维方式

我的想法,很常规,就是考虑复制指针的状态,看目前已经有多少个重复的了。

题解的想法,是考虑已有结果的状态!看结果中是否已经有两个相等了(因为有序,只需一个位置判断)。

代码

这里贴上自己想的方法,相对繁琐。

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        if(nums.size() < 3) { return nums.size() ; }
        const int DUPLICATE_LIMIT = 2 ;
        vector<int>::iterator dup_uniq_iter = nums.begin() ;
        int duplicates_cnt = 0 ;
        for(auto iter = nums.begin() + 1; iter < nums.end() ; ++iter)
        {
            if(*iter == *dup_uniq_iter)
            {
                ++duplicates_cnt ;
                if(duplicates_cnt < DUPLICATE_LIMIT)
                {
                    *++dup_uniq_iter = *iter ;
                }
            }
            else
            {
                *++dup_uniq_iter = *iter ;
                duplicates_cnt = 0 ;
            }
        }
        size_t newSz = dup_uniq_iter - nums.begin() + 1 ;
        nums.resize(newSz);
        return newSz;
    }
};

后记

关于迭代次与下标的速度比较:

对第二种方法,我写的迭代器版本:

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        size_t sz = nums.size() ;
        if(sz < 3){ return sz ; } // always satisfied
        vector<int>::iterator rear_iter = nums.begin() + 1 ;
        for(auto iter = nums.begin()+2 ; iter != nums.end(); ++iter)
        {
            if(*iter != *(rear_iter-1))
            {
                *++rear_iter = *iter ;
            }
        }
        return rear_iter - nums.begin() + 1 ;
    }
};

以上与下标版逻辑完全一致,然而迭代器版本跑了20ms,而下标版只需要16ms

这之间的差距时如何形成的呢?

注意for循环中的nums.end()调用!当我把它在循环前保存下来作为一个变量来代替时,即:

//for(auto iter = nums.begin()+2 ; iter != nums.end(); ++iter)
auto end_iter = nums.end() ;
for(auto iter = nums.begin()+2 ; iter != end_iter; ++iter)

迭代器的版本时间消耗也成为了16ms!

由此可见容器的end()调用其实也是一定程度耗时的(在此种情况下有些显著啊!!)

以后如果有超大量的循环,且容器是只读,那么存储尾后迭代器或许是有必要的。

版权声明:本文为博主原创文章[在个人GitHub上可能有相同技术文档],未经博主允许不得转载。

相关文章推荐

leetcode题解-80. Remove Duplicates from Sorted Array II

题目:Follow up for "Remove Duplicates": What if duplicates are allowed at most twice?For example, Give...

【LeetCode】80. Remove Duplicates from Sorted Array II解法及注释

80. Remove Duplicates from Sorted Array II Total Accepted: 71844 Total Submissions: 220521 Diff...

LeetCode - 80. Remove Duplicates from Sorted Array II

方法一: 这一种方法是第一个想到的,因为题目中要求删除的是出现两次及其以上的元素,所以在思考的时候想到了使用HashMap来记录数组中每个元素出现的次数,对于出现次数大于2的元素就删除。删除的方法是由...

【leetcode c++】80 Remove Duplicates from Sorted Array II

临近期末,转移战场,考完回家,家里怒报驾校,应接不暇。进正题 Remove Duplicates from Sorted Array II Follow up for "RemoveDupli...
  • hqq39
  • hqq39
  • 2015年07月17日 22:54
  • 292

leetcode 80. Remove Duplicates from Sorted Array II

leetcode 80. Remove Duplicates from Sorted Array II 题目大意:从排序好的数组中删除重复元素,最多允许重复次数为2次 解题思路:对于排序的数组,如果重...

Leetcode_80_Remove Duplicates from Sorted Array II

本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/43835055 Follow up for "...

LeetCode 80. Remove Duplicates from Sorted Array II

Follow up for "Remove Duplicates": What if duplicates are allowed at most twice? For example, Giv...

LeetCode26/27/80/75 Remove Duplicates from Sorted Array I and II/Remove Element/Set Colors**

题目: Given a sorted array, remove the duplicates in place such that each element appear only once an...

61. Rotate List\80. Remove Duplicates from Sorted Array II\209. Minimum Size Subarray Sum

Rotate List 题目描述 代码实现 Remove Duplicates from Sorted Array II 题目描述 代码实现 Minimum Size Subarray Sum 题目描...

26/80. Remove Duplicates from Sorted Array I/II(C++)

6点清晨的阳光真好。 开始成长的第一天,开始刷leetcode,新建了博客开始记录自己的成长。写下一些不懂的知识点慢慢进步,希望能真正感受到算法之美,也希望自己在本科毕业的时候能够如愿找到好工作。第...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[LeetCode]problem 80. Remove Duplicates from Sorted Array II
举报原因:
原因补充:

(最多只允许输入30个字)