想了解经典第一题和力扣的使用方法的,请点击下面链接:
力扣(LeetCode)经典第一题!两数之和!(python3)
该题属于简单类的,让我们先看看题目要求:
简单来说就是从一个从小到大排序的数组中删除重复项,返回删除后数组的长度。可以结合示例来理解:
那么这道题的解法其实很简单,数组中的一个元素我们不用判断,从第二个元素开始判断,看是否与前一个元素相同,如果不相同,则跳过,反之则删除,跳过容易,但删除怎么实现呢?相信有不少同学会使用remove方法来删除,但结果却是错误的,正确的代码如下:
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
j = 1
for i in range(1, len(nums)):
if nums[i] != nums[i-1]:
nums[j] = nums[i]
j += 1
return j
可以看到,这里并不是直接将元素删除,而是对数组下标进行赋值,j用来作为元素下标的同时,也控制了数组的长度,代码很容易理解。
那么remove方法为什么不能实现呢,这是因为使用remove方法时会改变数组中元素的下标排列,导致我们在遍历数组元素的时候会遗漏,以下面的代码为例:
nums = [0, 0, 1, 1, 1, 2, 2, 3, 3, 4]
for i in range(0, len(nums)-1):
for j in range(i+1, len(nums)-1):
if nums[i] == nums[j]:
nums.remove(nums[j])
这段代码运行的结果是:[0, 1, 1, 2, 3, 4],有一个1没有被删除,原因是,使用双指针进行遍历,当i指针指向第一个1时,j指针指向第二个1,这时判断两个元素相等,会把第二个1进行删除,那么删除之后会发生什么呢,答案是:i指针不动,j指针向后移一个单位,同时后面的元素会向前移动一个单位,第三个1会到第二个1的位置,然而j向后移动会指向第一个2,这就导致j指针和第三个1完美错过(你的名字是....bushi),所以结果中会多出来一个1。
真相大白!除此之外呢,双循环会使复杂度上升为o(n2),因为要遍历两次数组,代码的执行效率也会下降,如果代码执行的时间过长,提交后也会导致不能通过,小伙伴们还是要注意一下。