双指针法【Python】简单应用——移动元素

1、概述

        双指针法是一种常用的算法思想,用于解决数组和链表等数据结构的问题。它的基本思想是使用两个指针在数据结构中同时移动,以便有效地查找或比较元素。

在数组中,通常使用两个指针从两端向中间移动,以便查找满足特定条件的元素。在链表中,通常使用两个指针以不同的速度移动,以便在链表中查找环或回文字符串等问题。

双指针法也可以用于优化时间复杂度,例如:快速排序和归并排序等算法中常常使用双指针法。

2、例题

        给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

元素的顺序可以改变。无需要考虑数组中超出新长度后面的元素。

示例:给定 nums = [ 0, 1, 2, 2, 3, 0, 4, 2 ],val = 2,函数应该返回新的长度 5,并且 nums 中的前五个元素为 0, 1, 3, 0, 4。

无需考虑数组中超出新长度后面的元素。

思路:因为数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。

3、循环解法

遍历数组,找到要移除的数,则将后面的元素集体向前移动一位

# 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)

4、双指针法

定义快指针:寻找不是目标元素的数组 为新数组

定义慢指针:将新数组 更新 在指针指定的位置上

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),可以看出合理运用双指针法能节省时间资源,降低时间复杂度。

你可能感兴趣的:(Python,算法)