1:题目描述(力扣)
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
2:解题思路
使用双指针解法
解法一:快慢指针
初始值都是数组的第一个下标,向同一个方向移动
定义快慢指针:
快指针:用来获取新数组的元素
慢指针:指向新数组的下标位置
第一步:初始化慢指针,slow=0
第二步:对数组进行遍历,初始化快指针,for fast in range(len(nums))
第三步:当前快指针对应的数组元素与目标值不相等时,将快指针对应的元素复制给下标为慢指针的新数组,向右移动慢指针到下一个位置
第四步:遍历完整个数组后,慢指针的值即为新数组的长度
代码展示:
class Solution:
def removeElement(self, nums, val):
slow = 0 # slow为定义的慢指针
for fast in range(len(nums)): # fast为定义的快指针
if nums[fast] != val: # 快指针对应的数组元素不等于目标值
nums[slow] = nums[fast] # 将快指针对应的元素复制给下标为慢指针的新数组
slow += 1 # 将慢指针向右移动
return slow # 新数组的慢指针对应的值,即是新数组的长度
解法二:相向双指针解法
基于元素顺序可以改变的题目描述,改变了元素相对位置,确保了移动最少元素
第一步:初始化左右指针,left, right = 0, len(nums)-1
第二步:当left<=right时,进入循环,
第三步:在第二步的循环体内:找到左边等于目标值的元素下标:当left<=right并且左指针对应的数组元素不等于目标值(nums[left] != val)时,将左指针向右移动一位(left+=1),否则,说明当前左指针就是我们需要寻找的元素下标
第四步:在第二步的循环体内:找到右边不等于目标值的元素下标:当left<=right并且右指针对应的数组元素等于目标值(nums[left] != val)时,将右指针向左移动一位(right-=1),否则,说明当前右指针就是我们需要寻找的元素下标
第五步:如果left<right,则需要将当前不等于目标值的右指针对应的数组元素覆盖当前等于目标值的左指针对应的数组元素
代码展示:
class Solution:
def removeElement(self, nums, val):
left, right = 0, len(nums)-1 # 初始化左右指针
while left <= right:
# 找到左边等于目标值的元素下标
while left <= right and nums[left] != val:
left += 1
# 找到右边不等于目标值的元素下标
while left <= right and nums[right] == val:
right -= 1
# 将右边不等于目标值的元素,覆盖左边等于目标值的元素
if left <= right:
nums[left] = nums[right]
left += 1
right -= 1
return left
可参考:代码随想录