一:Remove Duplicates from Sorted Array
题目:
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]
.
链接:https://leetcode.com/problems/remove-duplicates-from-sorted-array/
分析:这道题很简单,就是移除有序数组中重复的元素,这里我给出三种方法。
法一:暴力
for(int i = 0; i < n; i++){ int j = 1; while((i+j)<n && A[i] == A[i+j]){ j++; } if(j > 1){ for(int k = i+j; k < n; k++) A[k-j+1] = A[k]; n = n-j+1; } } return n
结果是TLE,因为当元素是[-998,-998,-997,-997,-997...] 每遍历一次,都几乎需要移动O(n)次,很明显超时
法二:设了一个vector,简单多了,但是需要额外的空间,不知道怎么在leetcode上也通过了,时间复杂度为O(N),但是空间复杂度也为O(N) 不满足要求
if(n == 0) return 0; vector <int>v; v.push_back(A[0]); for(int i = 1; i < n; i++){ if(A[i] != v.back()) v.push_back(A[i]); } for(int i = 0; i < v.size(); i++) A[i] = v[i]; return v.size();
法三:设置一个计算器,用来统计不重复元素个数,当元素不同时,每当遍历前后元素不相同,计数器加1,并将当前遍历的元素放入计数器对应在数组中位置。it is amazing!!!也可以说是双指针的思想!!
class Solution { public: int removeDuplicates(int A[], int n) { // 法一: /* for(int i = 0; i < n; i++){ int j = 1; while((i+j)<n && A[i] == A[i+j]){ j++; } if(j > 1){ for(int k = i+j; k < n; k++) A[k-j+1] = A[k]; n = n-j+1; } } return n;*/ // 法二 这样也能 AC ? /*if(n == 0) return 0; vector <int>v; v.push_back(A[0]); for(int i = 1; i < n; i++){ if(A[i] != v.back()) v.push_back(A[i]); } for(int i = 0; i < v.size(); i++) A[i] = v[i]; return v.size();*/ // 法三 It is amazing!! if(n == 0) return 0; int index = 1; for(int i = 1;i < n; i++){ if(A[i] != A[i-1]){ A[index++] = A[i]; } } return index; } };
二:Remove Element
题目:
Given an array and a value, remove all instances of that value in place and return the new length.
The order of elements can be changed. It doesn‘t matter what you leave beyond the new length.
链接:https://leetcode.com/problems/remove-element/
分析:就是移除数组中==指定elem的元素。
方法一:先排序,后找到该元素,后通过移动进行删除,,--————麻烦复杂————O(NlgN)
sort(A, A+n); // 排序 int count = 0; int index = 0; for(int i = 0; i < n; i++){ // 记录==elem的元素个数及最后的下标 if(A[i] == elem){ count ++; index = i; } } for(int i = index+1; i < n; i++){ // 移动数组 A[i-count] = A[i]; } return n-count;
方法二:计数器法,遍历一次,如果该元素不等于elem,则将该元素放入计数器所定位的位置。计数器的位置小于等于当前遍历的下标,所以不会影响后续遍历。时间复杂度为O(N).
class Solution { public: int removeElement(int A[], int n, int elem) { int index = 0; for(int i = 0; i < n; i++){ if(A[i] != elem) A[index++] = A[i]; } return index; } };
三: Remove Duplicates from Sorted ArrayII
题目:
Follow up for "Remove Duplicates":
What if duplicates are allowed at most twice?
For example,
Given sorted array A = [1,1,1,2,2,3]
,
Your function should return length = 5
, and A is now [1,1,2,2,3]
.
链接:https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii/
分析:仍然是计数器+双指针的思想
class Solution { public: int removeDuplicates(int A[], int n) { if(n == 0 || n == 1)return n; int index = 1; for(int i = 1; i < n-1; i++){ if(A[i] != A[i-1] || A[i] != A[i+1]){ // 通过判断前一个元素与后一个元素 A[index++]= A[i]; } } A[index++] = A[n-1]; return index; } };