题目
分析
显然,由于数组已经排序,所以重复的元素一定连在一起,找出它们并不难,但如果毎找到一个重复元素就立即删除它,就是在数组中间进行删除操作,整个时间复杂度是会达到 O(N^2)。而且题目要求我们原地修改,也就是说不能用辅助数组,空间复杂度得是 O(1)。
其实,对于数组相关的算法问题,有一个通用的技巧:要尽量避免在中间删除元素,那我就先想办法把这个元素换到最后去。
这样的话,最终待删除的元素都拖在数组尾部,一个一个 pop 掉就行了,每次操作的时间复杂度也就降低到 O(1) 了。
按照这个思路呢,又可以衍生出解决类似需求的通用方式:双指针技巧。具体一点说,应该是快慢指针。
我们让慢指针slow走左后面,快指针fast走在前面探路,找到一个不重复的元素就告诉slow并让slow前进一步。
这样当fast指针遍历完整个数组nums后,nums[0…slow]就是不重复元素,之后的所有元素都是重复元素。
代码
ls=[2,3,4,1,5,6,87,45,9,2,4,3,1,7,6]
print("raw list: {}".format(ls))
ls=sorted(ls)
print("sorted list: {}".format(ls))
fast=1
slow=0
while fast<len(ls):
if ls[fast]!=ls[slow]:
slow+=1
ls[slow]=ls[fast]
fast+=1
print("result list: {}".format(ls[0:slow+1]))