[Leetcode] Remove Duplicates from Sorted Array 移除有序数组中的重复元素
Remove Duplicates from Sorted Array I
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 nums = [1,1,2],
Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length.
双指针法
复杂度
时间 O(N) 空间 O(1)
思路
我们可以将不重复的序列存到数列前面,因为不重复序列的长度一定小于等于总序列,所以不用担心覆盖的问题。具体来说,用两个指针,快指针指向当前数组遍历到的位置,慢指针指向不重复序列下一个存放的位置,这样我们一旦遍历到一个不重复的元素,就把它复制到不重复序列的末尾。判断重复的方法是记录上一个遍历到的数字,看是否一样。
代码
public class Solution { public int removeDuplicates(int[] nums) { if(nums.length == 0) return 0; int dup = nums[0]; int end = 1; for(int i = 1; i < nums.length; i++){if(nums[i]!=dup){ nums[end] = nums[i]; dup = nums[i]; end++;} } return end; }}
Remove Duplicates from Sorted Array II
Follow up for "Remove Duplicates": What if duplicates are allowed at most twice?
For example, Given sorted array nums = [1,1,1,2,2,3],
Your function should return length = 5, with the first five elements of nums being 1, 1, 2, 2 and 3. It doesn't matter what you leave beyond the new length.
双指针法
复杂度
时间 O(N) 空间 O(1)
思路
思路和上题一样,区别在于记录前两个遍历到的数字来帮助我们判断是否出现了第三遍。如果当前数字和前一个数字的前一个一样的话,说明出现了第三次。
代码
public class Solution { public int removeDuplicates(int[] nums) { if(nums.length <= 2) return nums.length; int dup1 = nums[0]; int dup2 = nums[1]; int end = 2; for(int i = 2; i < nums.length; i++){if(nums[i]!=dup1){ nums[end] = nums[i]; dup1 = dup2; dup2 = nums[i]; end++;} } return end; }}
Follow Up 后续
Q:如果数组没有排序的话如何解?
A:可以先将其排序再用同样方法求解,然而时间复杂度将达到O(N),如果我们改用哈希表或集合来记录数字出现次数,可以用O(N)空间得到O(N)的时间。