1、地址
https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/
2、题面分析
题目
题目信息
- 所有对数值的操作都需要最终在nums上
- 返回的整数len,表名nums[0, len-1]的部分是答案
- 超出的部分[len, nums.length -1]是可以用来做草稿的
的空间意味着我们只能设定常数个变量。
3、双指针 O(N)
求解思路
- 确定每一个需要的数
- 数组从小到大排序,通过前后比较可以确定每一个需要的数的位置
- 统计需要的数
- 没发现一个需要的数,统计值加一
- 移动需要的数
- 将需要的数移动到数组的最左边(需要的数的最右边)
TIPS:使用两个指针,第一个指针指向最后一个需要的数,第二个指针指向已经变了的数,直到遍历完成。
每次移动需要的数,第一个指针向后移动一位
代码实现
class Solution {public int removeDuplicates(int[] nums) {int len = nums.length;if(len < 2){return len;}int firstIndex = 0;int curIndex = 1;while(curIndex < len){int firstIndexNum = nums[firstIndex];int curNum = nums[curIndex];if(firstIndexNum != curNum){if(firstIndex < curIndex - 1){nums[++firstIndex] = nums[curIndex];curIndex++;}else{curIndex++;firstIndex++;}}else{curIndex++;}}return firstIndex + 1;}}
时间复杂度
总结
如果算法要求使用常数的额外空间进行求解,一般可以尝试在输入的变量中找到额外操作空间
4、位标记法(不推荐)
求解思路
- 不考虑O(1)的空间限制
- 标记每一个需要的数的下标
-
代码实现
class Solution {public int removeDuplicates(int[] nums) {int len = nums.length;if(len < 2){return len;}BitSet indexSet = new BitSet();indexSet.set(0);for(int i = 1; i < len; i++){if(nums[i] != nums[i-1]){indexSet.set(i);}}int retLen = 0;for(int i = 0; i < len; i ++){if(indexSet.get(i)){nums[retLen++] = nums[i];}}return retLen;}}
时间复杂度
-
总结
不推荐用这个方法,使用了两次循环遍历,而且使用了额外空间。只做参考使用,提供额外的解题思路
