LeetCode详解系列的总目录(持续更新中):
LeetCode详解之如何一步步优化到最佳解法:前100题目录(更新中...)-CSDN博客
LeetCode详解系列的上一题链接:
LeetCode详解之如何一步步优化到最佳解法:21. 合并两个有序链表-CSDN博客
目录
26. 删除有序数组中的重复项
本题题目链接:26. 删除有序数组中的重复项 - 力扣(LeetCode)
解法1:暴力解法
解法1思路:
根据题目的要求,即,将输入的数组中的所有的元素进行去重,并将去重后的元素按照递增的顺序(因为已经没有重复的元素了,所以前面的这些元素不存在“非严格递增排列”)存到输入数组的开头。
那么,这涉及到三个指针,第一个指针指向当前可能重复的元素最终应该放的位置;第二个指针指向一串连续相同元素的第一个位置;第三个指针指向一串连续相同元素的最后一个位置。
然后,就是遍历输入数组,停止的条件是第三个指针指向了数组之后。接着,要不断找到“一串连续相同元素”的起止位置,因此也用while循环来寻找,找到后,第二个指针指向的元素存到第一个指针指向的位置,第一个指针向后移一位,第二个指针指向第三个指针的位置,进行下一轮的查找。
最终的输出结果为第一个指针指向的索引值。
对应的代码如下所示:
代码:
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
pt_s, pt_m, pt_e = 0, 0, 0
length = len(nums)
while pt_e < length:
while pt_e < length and nums[pt_m] == nums[pt_e]:
pt_e += 1
nums[pt_s] = nums[pt_m]
pt_s += 1
pt_m = pt_e
return pt_s
解法性能:
优化思路:
其实,第二个和第三个指针是想要找到一个界限,这个界限的左边元素和右边元素不一样,即,nums[pt_e-1] ≠ nums[pt_e]。那么,我们第二个指针和第三个指针其实只需要一个指针即可。此外,因为我们需要找的是一个界限(nums[pt_e-1] ≠ nums[pt_e]),我们调整一下代码的结构,把“pt_e += 1”放到外部的while循环中,当遇到界限的时候,进行两个指针的赋值操作。
然后,剩下的两个指针中,第二个指针要从索引为1开始。
在优化完这些后,代码如下所示:
解法2:最终版
代码:
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
if len(nums) == 1:
return 1
pt_s, pt_e = 1, 1
length = len(nums)
while pt_e < length:
if nums[pt_e-1] != nums[pt_e]:
nums[pt_s] = nums[pt_e]
pt_s += 1
pt_e += 1
return pt_s
解法性能:
解法分析:
在优化后,因为需要的变量减少,以及代码数量减少,占用的内存变少。
此外,因为减少了赋值的操作,所以用时也减少了。