双指针法是一种常用的算法思想,用于解决数组和链表等数据结构的问题。它的基本思想是使用两个指针在数据结构中同时移动,以便有效地查找或比较元素。
在数组中,通常使用两个指针从两端向中间移动,以便查找满足特定条件的元素。在链表中,通常使用两个指针以不同的速度移动,以便在链表中查找环或回文字符串等问题。
双指针法也可以用于优化时间复杂度,例如:快速排序和归并排序等算法中常常使用双指针法。
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。无需要考虑数组中超出新长度后面的元素。
示例:给定 nums = [ 0, 1, 2, 2, 3, 0, 4, 2 ],val = 2,函数应该返回新的长度 5,并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
无需考虑数组中超出新长度后面的元素。
思路:因为数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。
遍历数组,找到要移除的数,则将后面的元素集体向前移动一位
# 1、定义移动函数,接收数组和目标数
def move(nums, val):
# 2、设置索引,获取数组长度
i, l = 0, len(nums)
# 3、遍历数组
while i < l:
# 4、找到要移除的元素
if nums[i] == val:
# 5、遍历目标数之后的元素
for j in range(i+1, l):
# 6、后续集体数组前移
nums[j-1] = nums[j]
# 长度减一
l -= 1
i -= 1
i += 1
return l, nums
if __name__ == '__main__':
nums = [0, 1, 2, 2, 3, 0, 4, 2]
print(move(nums, 2))
可以看出这种解法的时间复杂度为O(n^2),空间复杂度为O(1)
定义快指针:寻找不是目标元素的数组 为新数组
定义慢指针:将新数组 更新 在指针指定的位置上
def move(nums, val):
fast = 0 # 快指针
slow = 0 # 慢指针
while fast < len(nums):
if nums[fast] != val:
# slow 用来收集不等于 val 的值,如果 fast 对应值不等于 val,则把它与 slow 替换
nums[slow] = nums[fast]
slow += 1
fast += 1
return slow
if __name__ == '__main__':
nums = [0, 1, 2, 2, 3, 0, 4, 2]
print(move(nums, 2))
这种解法的时间复杂度为O(n),空间复杂度为O(1),可以看出合理运用双指针法能节省时间资源,降低时间复杂度。