Swift 数据结构与算法( 20) 链表 + Leetcode203. 移除链表元素

53 阅读2分钟

概念

题目

203. 移除链表元素

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

 

示例 1:

输入: head = [1,2,6,3,4,5,6], val = 6
输出: [1,2,3,4,5]

示例 2:

输入: head = [], val = 1
输出: []

示例 3:

输入: head = [7,7,7,7], val = 7
输出: []

 

提示:

  • 列表中的节点数目在范围 [0, 104] 内
  • 1 <= Node.val <= 50
  • 0 <= val <= 50

解题思路🙋🏻‍ ♀️

链表:[1,2,6,3,4,5,6]。目标:删除值为 4 的节点。


初始化:

dummy -> 1 -> 2 -> 6 -> 3 -> 4 -> 5 -> 6
pre -> 1 -> 2 -> 6 -> 3 -> 4 -> 5 -> 6
current -> 1 -> 2 -> 6 -> 3 -> 4 -> 5 -> 6

第一次循环:

  • current.val 不等于 4,所以 pre 移动到 current
  • current 移动到下一个节点。
dummy -> 1 -> 2 -> 6 -> 3 -> 4 -> 5 -> 6
pre -> 1 -> 2 -> 6 -> 3 -> 4 -> 5 -> 6
current -> 2 -> 6 -> 3 -> 4 -> 5 -> 6

第二次循环:

  • current.val 不等于 4,所以 pre 移动到 current
  • current 移动到下一个节点。
dummy -> 1 -> 2 -> 6 -> 3 -> 4 -> 5 -> 6
pre -> 2 -> 6 -> 3 -> 4 -> 5 -> 6
current -> 6 -> 3 -> 4 -> 5 -> 6

第三次循环:

  • current.val 不等于 4,所以 pre 移动到 current
  • current 移动到下一个节点。
dummy -> 1 -> 2 -> 6 -> 3 -> 4 -> 5 -> 6
pre -> 6 -> 3 -> 4 -> 5 -> 6
current -> 3 -> 4 -> 5 -> 6

第四次循环:

  • current.val 不等于 4,所以 pre 移动到 current
  • current 移动到下一个节点。
dummy -> 1 -> 2 -> 6 -> 3 -> 4 -> 5 -> 6
pre -> 3 -> 4 -> 5 -> 6
current -> 4 -> 5 -> 6

第五次循环:

  • current.val 等于 4,所以 pre.next 跳过 current 并直接指向 current.next
  • current 移动到下一个节点。
dummy -> 1 -> 2 -> 6 -> 3 -> 5 -> 6
pre -> 3 -> 5 -> 6
current -> 5 -> 6

第六次循环:

  • current.val 不等于 4,所以 pre 移动到 current
  • current 移动到下一个节点。
dummy -> 1 -> 2 -> 6 -> 3 -> 5 -> 6
pre -> 5 -> 6
current -> 6

最后一次循环:

  • current.val 不等于 4,所以 pre 移动到 current
  • current 移动到下一个节点 (变为 nil)。
dummy -> 1 -> 2 -> 6 -> 3 -> 5 -> 6
pre -> 6
current -> nil

最终结果:

dummy -> 1 -> 2 -> 6 -> 3 -> 5 -> 6

链表成功删除了值为 4 的节点。

边界思考🤔

if current!.val == val这里我们检查当前节点的值是否等于要删除的值。 pre!.next = current!.next 如果当前节点的值等于要删除的值,我们不直接删除 current 节点,而是通过改变 prenext 指针来跳过 current 节点,从而实现删除操作。 else: 如果当前节点的值不等于要删除的值,我们不需要做任何删除操作。 pre = current: 我们将 pre 指针移动到 current,意味着在下一次循环中,pre 将始终指向 current 的前一个节点。

代码

class Solution {
    func removeElements(_ head: ListNode?, _ val: Int) -> ListNode? {
        
        if head == nil {
            return nil
        }
        var dummy = ListNode(0)
        dummy.next = head
        var pre: ListNode? = dummy
        var current: ListNode? = dummy
        
        // 如果 current != nil  继续循环. ;
        while current != nil {
            
            if current!.val == val {
                pre!.next = current!.next
            } else {
                pre = current
            }
            current = current!.next
        }
        
        return dummy.next
    }
}

时空复杂度分析

O(n)

截屏2023-08-08 23.47.38.png

引用

本系列文章部分概念内容引用 www.hello-algo.com/

解题思路参考了 abuladong 的算法小抄, 代码随想录... 等等

Youtube 博主: huahua 酱 nick , 等等.