Leetcode--移除元素(27)

题目描述:给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

 

 

(1)思路一: 直接使用python中的remove函数,移除列表中某个值的第一个匹配项。

1 class Solution:
2     def removeElement(self, nums: List[int], val: int) -> int:
3         while val in nums:
4             nums.remove(val)
5         return len(nums)

 

 

 时间复杂度:O(n)

(2)思路二:类似删除重复项(26),使用双指针。同样是一个快指针和一个慢指针,慢指针用来记录最终的nums,快指针用来遍历列表中的所有元素。

 1 class Solution:
 2     def removeElement(self, nums: List[int], val: int) -> int:
 3         length =len(nums)
 4         i = 0
 5         j = 0
 6         while j < length:
 7             if nums[j] != val:
 8                 nums[i] = nums[j]
 9                 i += 1
10             j += 1
11         return i

 时间复杂度O(n),假设数组共有n个元素,i和j至少遍历2n步        空间复杂度O(1)        时间及内存消耗: 

 

 

 优化:

当列表中需要删除的元素出现次数很少时,例如[4,1,2,3,5]要移除4时,如果采用上述双指针法则需要依次对前四个元素进行左移操作。而由于题目中提到,元素的顺序可以改变。因此在这种情况下,其实只需要将4和列表中的最后一个元素交换位置即可。因此有一种更为优雅的双指针方法:两个指针i和j分别指向头和尾,当i所指向的值等于所需要删除的值时,则将i与j所指向的元素互换,同时j-1;否则直接i+1即可。

 1 class Solution:
 2     def removeElement(self, nums: List[int], val: int) -> int:
 3         i = 0
 4         j = len(nums)
 5         while i < j:
 6             if nums[i] == val:
 7                 nums[i] = nums[j-1]
 8                 j -= 1
 9             else:
10                 i += 1
11         return j

时间复杂度:O(n),在此种方法中,i和j相遇最多需要遍历n步,因此更加高效。

 

posted @ 2020-03-07 15:20  eltShawn  阅读(184)  评论(0)    收藏  举报