快慢指针的应用

快慢指针的在leetcode的问题中有很多应用,例如通过一次遍历找到链表的中间节点。 这里要介绍的是作为哨兵,应用于数组或者链表中删除特定元素,不另外开辟空间,即空间复杂度为O(1)

删除有序数组中的重复项

leetcode 26
在这里插入图片描述
在这里插入图片描述
因为是有序数组,所以重复的元素都是在一起的。暴力处理,每次判断当前元素和后一个元素是否相同,不相同则删除,而删除需要移动后面的元素,时间复杂度为O(n^2)

使用快慢指针,slow记录的是不同元素的索引。fast作为哨兵,一开始指向slow的下一个元素,如果遇到不同的元素,则slow + 1,将fast指向的值赋值给slow指向的值, 最后返回数组的长度为slow + 1(索引从0开始,长度需要+1)。 此时数组中的前 slow + 1个元素都有不同的值。

代码如下:

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        if len(nums) == 0:
            return 0
        slow = 0
        nums_len = len(nums)
        for fast in range(1,nums_len):
            if nums[fast] != nums[slow]:
                slow += 1
                nums[slow] = nums[fast]
        return slow + 1

时间复杂度为:O(n)
空间复杂第为: O(1)

删除排序链表中的重复元素

leetcode 83

在这里插入图片描述
在这里插入图片描述

方法和上一题一样,这里需要注意,链表需要将slow的下一个节点置为None

代码如下:

class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        if not  head:
            return None
        slow,fast = head,head
        while fast.next:
            fast = fast.next
            if fast.val != slow.val:
                slow = slow.next
                slow.val = fast.val
        slow.next = None
        return head

时间复杂度为:O(n)
空间复杂第为: O(1)

移除特定元素

letcode 27
在这里插入图片描述
在这里插入图片描述
同样利用使用快慢指针。

slow初始值为-1,不指向任何元素,因为有可能整个数组都是待删除的元素fast作为哨兵,从头遍历。如果遇到不等于val的元素,则slow + 1,将fast指向的值赋值给slow指向的值, 最后返回数组的长度为slow + 1

代码如下:

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        if len(nums)  == 0:
            return 0
        nums_len = len(nums)
        slow = -1  # 
        for fast in range(nums_len):
            if nums[fast] != val:
                slow += 1
                nums[slow] = nums[fast]
        return slow + 1

时间复杂度为:O(n)
空间复杂第为: O(1)

移动零

letcode 283

在这里插入图片描述
思路于上面一个问题一样,只不过这里不是移除元素0,而是要将元素0移至末尾,因此这里要进行元素的交换,而不是直接赋值

代码如下:

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        if len(nums)==0:
            return
        slow = -1
        nums_len = len(nums)
        for fast in range(nums_len):
            if nums[fast] != 0:
                slow += 1
                # 进行元素的交换,而不是直接赋值
                tmp = nums[slow]
                nums[slow] = nums[fast]
                nums[fast] = tmp

时间复杂度为:O(n)
空间复杂第为: O(1)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旺旺棒棒冰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值