您的位置:首页 > 其它

LeetCode(26)Remove Duplicates From Sorted Array

2013-12-31 08:37 579 查看
题目如下

Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length.

Do not allocate extra space for another array, you must do this in place with constant memory.

For example,

Given input array A = [1,1,2],

Your function should return length = 2, and A is now [1,2].

题目分析

和上面一道题目比较类似。但是本题在题目中明确要求,不仅要返回滤重后的length而且要保证原数组的前length个数是滤重后的结果。我的想法比较直观,直接遍历数组,针对每个元素,把这个元素和它右边的元素进行两两比较。如果不相同则向右继续进行比较,如果相同则把重复的元素删除并且进行新的比较。因为是在数组中删除,所以每次都需要把待删除元素的右侧的元素逐个地左移,效率较低。

//88ms
class Solution {
public:
    int removeDuplicates(int A[], int n) {
        for(int i=0;i<n-1;i++){
            if(A[i]==A[i+1]){
                for(int j=i+1;j<n-1;j++)
                    A[j]=A[j+1];
                n--;
                i--;
            }
        }
        return n;
    }
};

为了提高效率,需要避免把待删除的元素逐个进行左移。为了实现这一点。可以不断地把不需要删除的元素依次从左到右放入一个新数组。实际上由于新数组是滤重后的数组,总是比原数组短或者相等。所以可以共用新数组和原数组的空间。也就是,对A数组,一边检查没两个元素是否相等,一边生成新数组。以[1,1,2,3,4,4,4,]为例。

起始状态,先把第0个元素放入新数组,也就是把1放入新数组。然后开始比较第0个元素和第1个元素。也就是比较1和1.

1和1比较,二者相等,所以不放数字进入新数组,新数组中下一个待放入的下标为1。

1和2比较,二者不等,所以把2放入新数组,放入下标为1的地方,新数组中下一个待放入的下标为2。

2和3比较,二者不等,所以把3放入新数组,放入下标为2的地方,新数组中下一个待放入的下标为3。

3和4比较,二者不等,所以把4放入新数组,放入下标为3的地方,新数组中下一个待放入的下标为4。

4和4比较,二者相等,所以不放数字进入新数组,比较下一个数字,也就是第3个4.

4和4比较,二者相等,所以不放数字进入新数组,比较下一个数字,发现到达数组结尾,结束。

代码如下

// 80ms
class Solution {
public:
    int removeDuplicates(int A[], int n) {
        if(n<=0)
            return 0;
        int i=0;
        int j=i+1;
        while(j<n){
            if(A[i]!=A[j]){
                A[i+1]=A[j];
                i++;
                j++;
            }else{
                j++;
            }
        }
        return i+1;
    }
};
经过更改后,理论上时间复杂度由O(N²)变化为了O(N)。实际上测试表明,只是从88ms降低到了80ms。。。。

于是网上搜之,看到leetcode官网上一个更简洁的写法。思路和上面第2种一样,但是语言更简洁。测试了一下,这个通过大集合只需要56ms.

//56ms
class Solution {
public:
    int removeDuplicates(int A[], int n) {
        if (n < 2) return n;
        int len = 1;
        for(int i = 1; i < n; ++i) {
            if(A[i] != A[len - 1]) {
                A[len++] = A[i];
            }
        }
        return len;
    }
};


update: 2014-10-09

在原数组的基础上从左到右生成新数组,用keep_index表示留存下来的数,也就是新数组的下标。用index表示原数组的下标。思路和这道remove element很像。

class Solution {
public:
    int removeDuplicates(int A[], int n) {
        if (n < 1) return n;
        int keep_index = 0;
        int index = 1;
        while (index < n) {
            if (A[keep_index] != A[index]) { 
                ++keep_index;
                A[keep_index] = A[index];
            }
            ++index;
        }
        return keep_index + 1;
    }
};


update: 2015-01-10

写了remove duplicates from sorted arrayII之后,发现这两道题目基本思路非常像。用了我最熟悉的风格来写这道题目,如下:

//33ms
class Solution {
public:
    int removeDuplicates(int A[], int n) {
        int i = 0, j = 0;
        while (i < n && j < n) {
            if (j + 1 < n && A[j] == A[j + 1]) {
                A[i] = A[j];
                ++i;
                while (A[j] == A[i - 1])
                    ++j;
            }else {
                A[i] = A[j];
                ++i;
                ++j;
            }
        }
        return i;
    }
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: