LeetCode 203. 移除链表元素 迭代 递归

294 阅读2分钟

题目描述

题目来源:力扣(LeetCode)
题目链接:203. 移除链表元素

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

removelinked-list.jpg

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

示例 2:

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

提示:

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

解题方法一:迭代

思路

建立一个包含哑节点的单链表,记录其尾节点。

  • 因为原链表头节点可能被删除,为了方便指针操作需要哑节点。 遍历原链表,当需要保留节点时,通过尾插法插入到新链表;当需要删除节点时,通过指针变换移除该节点,并释放内存。

代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        // dummy 为哑节点,tail 为尾节点
        auto dummy = new ListNode(0, head), tail = dummy;
        // 还存在待处理节点
        while(tail->next) {
            if(tail->next->val == val) {
                // tmp 为待删除节点
                auto tmp = tail->next;
                // 从链表移除 tmp
                tail->next = tmp->next;
                // 释放内存
                delete tmp;
            }else {
                // 往右移动
                tail = tail->next;
            }
        }
        // 更新head
        head = dummy->next;
        // 释放内存
        delete dummy;
        return head;
    }
};

解题方法二:递归

思路

removeElements 能够删除以 head 为头节点的单链表中的等于 val 的节点,并且返回新的头节点。那么递归出口为 head 是空指针。

代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        // 递归出口
        if(!head) {
            return head;
        }
        // 递归
        head->next = removeElements(head->next, val);
        // 需要删除当前节点
        if(head->val == val) {
            auto tmp = head;
            // 更新 head
            head = head->next;
            // 释放内存
            delete tmp;
        }
        return head;
    }
};