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个数是滤重后的结果。我的想法比较直观,直接遍历数组,针对每个元素,把这个元素和它右边的元素进行两两比较。如果不相同则向右继续进行比较,如果相同则把重复的元素删除并且进行新的比较。因为是在数组中删除,所以每次都需要把待删除元素的右侧的元素逐个地左移,效率较低。
为了提高效率,需要避免把待删除的元素逐个进行左移。为了实现这一点。可以不断地把不需要删除的元素依次从左到右放入一个新数组。实际上由于新数组是滤重后的数组,总是比原数组短或者相等。所以可以共用新数组和原数组的空间。也就是,对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比较,二者相等,所以不放数字进入新数组,比较下一个数字,发现到达数组结尾,结束。
代码如下
于是网上搜之,看到leetcode官网上一个更简洁的写法。思路和上面第2种一样,但是语言更简洁。测试了一下,这个通过大集合只需要56ms.
update: 2014-10-09
在原数组的基础上从左到右生成新数组,用keep_index表示留存下来的数,也就是新数组的下标。用index表示原数组的下标。思路和这道remove element很像。
update: 2015-01-10
写了remove duplicates from sorted arrayII之后,发现这两道题目基本思路非常像。用了我最熟悉的风格来写这道题目,如下:
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; } };
相关文章推荐
- 读书笔记-《基于Oracle的SQL优化》-第二章-1
- 面试题之自创 实现两个整型大数(都是正数)的相减操作
- 关于程序员的59条搞笑但却真实无比的编程语录
- 在页面上用action传递参数到后台出现乱码的解决方法
- WebService开发实例(java代码)
- Mapr使用数据
- 有效逻辑地址所对应的物理地址
- 2013年EMR软件实施年终总结
- Mass Spectrometry Blog
- Mapr与Mapr-FS工作(二)——块大小
- Android桌面悬浮窗进阶,QQ手机管家小火箭效果实现
- Mapr与Mapr-FS工作(一)——块大小
- 2013年终总结,我这一年的点点滴滴
- 网络速率方面单位MBPS和MB的区别
- 模拟鼠标键盘对TextBox光标进行操作
- EXCEL填充空白行
- 数据库优化实践【索引篇】
- 文件I/O(不带缓冲)之原子操作
- getchar和getch的区别,gets和scanf("%s",&k)的区别
- Java开发牛人十大必备网站