2021/07/23 难度:简单
https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array
题目
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
解答
第一天刷题,其实我对这道题是没有思路的,在想了十分钟之后果断去看了题解,然后自己想了一遍,理解双指针是什么。
读题(理解题目意思)
首先注意数组是有序的,那么重复的元素一定会相邻。(读题的时候我 get 不到这个意思)
要求删除重复元素,实际上就是将不重复的元素移到数组的左侧。(我只想到了删除元素)
思考
考虑用 2 个指针,一个在前记作 p,一个在后记作 q。
算法流程如下:
- 判断指针 p 和指针 q 所指向的元素是否相等;
- 如果相等,指针 q 后移一位;如果不相等,将指针 q 指向的元素复制到指针 p+1 位置上,指针 p 后移一位,指针 q 也后移一位;
- 重复上述过程,直到指针 q 等于数组长度。
- 返回 p + 1,即为结果数组的长度。
具体的理解就是:
【0,0,1,1,1,2,2,3,3,4】
我有一堆已排序好的号码牌,我需要把不重复的数字按序排在前面。
-
如果第一个和第二个是相同的数字,那么第二个位置肯定要被替换掉的。
-
那么对比第一个和第三个数字,如果数字不相同,把第三个数字替换到第二个位置,就变成了:
【0,1,1,1,1,2,2,3,3,4】
然后,这时候第一个位置和第二个位置肯定是不重复的了,第二个位置和第三个位置肯定是重复的。所以开始对比第二个和第四个数字,如果相同,那么第四个位置也是要被后面的替换的。
重复以上过程:(红色代表初始比对值)
初始值:【0,0,1,1,1,2,2,3,3,4】
第一次:【0,1,1,1,1,2,2,3,3,4】
第二次:【0,1,2,1,1,2,2,3,3,4】
第三次:【0,1,2,3,1,2,2,3,3,4】
第四次:【0,1,2,3,4,2,2,3,3,4】
代码
function removeDuplicates(nums: number[]): number {
let p = 0;
for(let q = 1; q < nums.length; q++) {
if(nums[p] !== nums[q]) {
nums[++p] = nums[q];
}
}
nums.length = p + 1;
return nums.length;
};
复杂度分析
时间复杂度:O(n),其中 n 是数组的长度。快指针和慢指针最多各移动 n 次。
空间复杂度:O(1)。只需要使用常数的额外空间。