题目:给你一个升序排列
的数组nums
,请你原地
删除重复出现的元素,使每个元素
只出现一次 ,返回删除后数组的新长度。元素的相对顺序
应该保持 一致 。由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有k
个元素,那么nums
的前k
个元素应该保存最终结果。将最终结果插入nums
的前k
个位置后返回k
。
不要使用额外的空间,你必须在原地
修改输入数组并在使用 O(1) 额外空间的条件下完成。
来源:https://leetcode.cn/leetbook/read/all-about-array/x9a60t/
示例:
输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。
方法一:双指针正序查找
由于数组已经按顺序排好,因此i指着负责从前写入,j指针负责寻找每组重复元素的第一个出现的元素;每当j发现一个新的元素,i指针后移一位,并在新的位置上记录这个新元素。
def removeDuplicates(self, nums):
l = len(nums)
i = 0
j = 1
while j < l:
if nums[i] != nums[j]:
i += 1
nums[i] = nums[j]
j += 1
return (i+1)
方法二:双指针逆序查找
双指针从数组的最后向前遍历,若两个指针指向的元素相等,删除right指针所示元素,right指针指向left的位置,left向前移一位。
def removeDuplicates(self, nums):
nlen = len(nums)
left,right = nlen-2,nlen-1
while left >=0:
if nums[left] == nums[right]:
del nums[right]
right = left
left -= 1
return nlen
# 作者:WEI
# 链接:https://leetcode.cn/leetbook/read/all-about-array/x9a60t/?discussion=w58nRs
# 来源:力扣(LeetCode)
# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
方法三:单指针逆序查找
单指针i从排好序的数组末端向前遍历,因为排好序的数组必定后面的元素大于前面的元素,因此若查找的后面的元素小于或等于前面的,直接删除该元素。
def removeDuplicates(self, nums):
for i in range(len(nums)-1, 0, -1):
if nums[i] <= nums[i-1]:
del nums[i]
return len(nums)
# 作者:匿名用户
# 链接:https://leetcode.cn/leetbook/read/all-about-array/x9a60t/?discussion=hGQw7i
# 来源:力扣(LeetCode)
# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
标准答案
def removeDuplicates(self, nums):
n = len(nums)
if n == 0 or n ==1:
return n
# nums[0,i]为非重复数列
i = 0
j = i + 1
while j <= n-1:
if nums[j] != nums[i]:
# 指向同一个元素不需要赋值
if i + 1 != j:
nums[i+1] = nums[j]
i += 1
j += 1
return i + 1