删除排序数组中的重复项 给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
- 最初思路,使用for循环
l = len(nums)
j=1
for i in range(0, l):
if i == 0:
continue
j=j+1
else:
if nums[i] in nums[:i]:
del nums[i]
return len(nums)
出现的错误:
分析原因:使用循环的思想逐个判断元素并删除的思路是正确的,但在del之后,num的长度变小了,此时l不变,所以索引超出范围。
解决方法:再使用一个新的变量j,来控制nums的索引。
l = len(nums)
j=1
for i in range(0, l):
if i == 0:
continue
j=j+1
else:
if nums[j] in nums[:j+1]:
del nums[j]
else:
j=j+1
print(nums)
结果: [1,1,2]变成了[1].
分析原因:
if nums[j] in nums[:j+1]:
改为
if nums[j] in nums[:j]:
将第n个待检查的与前n-1个相比较。运行结果通过。
- 尝试使用while循环
def removeDuplicates2(nums):
"""
:type nums: List[int]
:rtype: int
"""
j=1
while(j<len(nums)):
if nums[j] in nums[:j]:
del nums[j]
else:
j=j+1
print(nums)
return
运行结果通过。
使用while循环,可以只用一个变量控制,不用像for循环一样,一个控制nums长度,一个控制原本的元素个数。
- 官方推荐——双指针
首先注意数组是有序的,那么重复的元素一定会相邻。 要求删除重复元素,实际上就是将不重复的元素移到数组的左侧。
考虑用 2 个指针,一个在前记作 p,一个在后记作 q,算法流程如下:
1.比较 p 和 q 位置的元素是否相等。
如果相等,q 后移 1 位 如果不相等,将 q 位置的元素复制到 p+1 位置上,p 后移一位,q 后移 1 位 重复上述过程,直到 q
等于数组长度。返回 p + 1,即为新数组长度。
首先注意数组是有序的,那么重复的元素一定会相邻。
要求删除重复元素,实际上就是将不重复的元素移到数组的左侧。
考虑用 2 个指针,一个在前记作 p,一个在后记作 q,算法流程如下:
1.比较 p 和 q 位置的元素是否相等。如果相等,q 后移 1 位
如果不相等,将 q 位置的元素复制到 p+1 位置上,p 后移一位,q 后移 1 位
2.重复上述过程,直到 q 等于数组长度。返回 p + 1,即为新数组长度。
p=0
q=1
while(q<len(nums)):
if (nums[p]!= nums[q]):
nums[p+1]=nums[q]
p=p+1
q=q+1
print(nums)
优化:
p=0
q=1
while(q<len(nums)):
if (nums[p]!= nums[q]):
if q-p >1:
nums[p+1]=nums[q]
p=p+1
q=q+1
print(nums)
- C++语言
学过的全忘光了,捡起来C++再说吧。