[LeetCode] Remove Duplicates from Sorted Array

来源:互联网 发布:杭州电商美工培训 编辑:程序博客网 时间:2024/05/22 16:51

Remove Duplicates from Sorted Array

已知:给定一个按照升序排列好的数组,该数组中的元素有些是重复出现的。

所求:将数组中重复的元素删除,所有的元素仅出现一次。

要求:不要申请新的空间,在固定数量的内存空间上设计算法。LeetCode中的in place表示原地,现场的意思,表示不再使用A之外的内存。

例子:

    给定数组 A = [1, 1, 2]

    返回新数组长度2,此时A = [1, 2]。

提示:Array, Two Pointers


思路:

    1、数组A在算法执行的过程中从前向后重新赋值,假设重新赋值后的数组记为A',A'随着算法的进行不断扩展。A和A'共用一段内存空间。

    2、在一个for循环中使用两个下标i和j。i表示当前处理的数组A中的元素下标,j表示数组A'的最后一个元素下标。可以理解为属于A,j属于A’。

    3、使用for循环对A中的元素逐一遍历,当i所在的元素与j所在的元素不相等时,说明A'中没有A[i]元素,此时将i所在的元素A[i]插入到j+1的位置上。A'得到扩展。

代码:

class Solution {public:    int removeDuplicates(int A[], int n) {        if( n == 0 )            return 0;                    int j = 0;        for( int i = 1; i < n; i++ ){            if( A[i] != A[j] ){                A[++j] = A[i];            }        }        return j+1;    }};
代码分析:

第4行和第5行处理了当传入的数组A为空时的特殊情况。

第8行开始的for循环到第12行结束,该for循环的循环变量为i,通过i依次访问数组A当中的每一个元素。第7行定义的j在第10行使用,同时在for循环内部不断变化。变量i和变量j是数组A的两个下标,LeetCode提示中的Two Pointers在此变形为i和j这两个下标。

算法会在执行的过程中从前向后不断改变A中的元素,假设被改变后的数组记为A',循环变量j就是A'的最后一个元素。而A'就是所求的数组。

for循环中只针对A[i] != A[j]的情况作了分支。表示循环会找到第一个与A[j]不同的元素的位置,该元素对于A'是一个新的不重复的元素,于是A'被扩展。A'被扩展表现在第10行,下标增加1,然后在新的最末位置插入不重复的元素A[i]。for循环继续执行,找到与A'数组最末一个元素不同的元素,然后加入到A'数组中。最后得到的A'数组一定包含了A中的所有元素,并且保证每个元素仅出现一次。

在这里需要注意,A'其实与A指向同一组内存空间,A'的长度小于或等于A。因此,算法满足题目的要求(不申请额外的空间,使用常数个存储空间)。

Remove Duplicates from Sorted Array II

已知:给定一个按照升序排列好的数组,该数组中的元素有些是重复出现的。

所求:删除部分重复元素,使得数组中重复次数大于或等于2的元素仅重复两次,出现1次的元素仍然出现1次。

要求:不要申请新的空间,在固定数量的内存空间上设计算法。

例子:

    给定数组 A = [1, 1, 1, 2, 2, 3]

    返回新数组长度5,此时A = [1, 1, 2, 2, 3]。

提示:Array, Two Pointers


思路:

    加入一个bool变量,在循环的过程中判断第i个元素是不是第一个与第j个元素相同的元素,如果是,则加入到A'中;如果不是,则不加入A'。

代码:

class Solution {public:    int removeDuplicates(int A[], int n) {        if(n==0)    return 0;                int j = 0;        bool moveSecondEle = true;        for(int i = 1; i < n; i++) {            if(moveSecondEle && A[j]==A[i]){                A[++j] = A[i];                moveSecondEle = false;            }else if(A[j]!=A[i]) {                A[++j] = A[i];                moveSecondEle = true;            }        }        return j+1;    }};

代码分析:

第7行在for循环开始前定义了一个布尔变量moveSecondEle,这个变量用来判断位置i上的元素是否是第1个与位置j上的元素相等的元素。moveSecondEle初始为true,当第一次出现A[j]等于A[i]时,将A[i]加入到A'中,加入的元素是A[j]在A’中第二次出现,故我使用了moveSecondEle这个变量名。之后,moveSecondEle变为false,在遇到与A[j]相同的元素也无法加入到A'中。

这个方法可以拓展,将moveSecondEle声明为int型,就可以使得A‘中的可重复元素变为3、4或者其他。


0 0
原创粉丝点击