Leetcode-203-移除链表元素

93 阅读2分钟

题目

给你一个链表的头节点 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,null]
  • 将判断链表分为两部分
    • 一个是判断当前节点
    • 一个是判断剩余链表
    • 1 和 [2,6,3,4,5,6,null]
    • 2 和 [6,3,4,5,6,null]
    • 6 和 [3,4,5,6,null]
    • 3 和 [4,5,6,null]
    • 。。。
    • 6 和 [null]
  • 所以判断当前是否满足 当前满足 return head
  • 当前不满足 return head.next (删除当前节点)
// next交给递归去处理
head.next = 递归(head.next,val);
// 出栈之后只判断自身
if(head.val == val) return head.next
else return head;

代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        // [] 空链表
        // dumyNode->1->3->1->2->4->null  头节点val 中间 val 尾巴val
        if(head == null) return head;
        // 加一个虚拟头节点 用于返回结果
        ListNode dumyNode = new ListNode(0, head);
        // 加一个pre 用于遍历整个链表
        ListNode pre = dumyNode; 
        while(pre.next != null){  // pre.next 其实就是(cur) 从链表头结点开始判断每一个节点是否有值
            if(pre.next.val == val){
                // 如果想等 删除 pre.next(cur)
                pre.next = pre.next.next;
            }else{
                // 不相等 保留当前 遍历下一个节点
                pre = pre.next;
            }
        }
        // 返回新的头节点
        return dumyNode.next;
    }
}
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    // 递归解法
    // 比如 [1,2,6,3,4,5,6] val = 6
    // 第一层 开始缩小为 cur = 1 cur.next = [2,6,3,4,5,6]
    // 第二层 继续缩小为 cur = 2 cur.next = [6,3,4,5,6]
    // 第三层 继续缩小为 cur = 6 cur.next = [3,4,5,6]
    // 第四层 继续缩小为 cur = 3 cur.next = [4,5,6]
    // 第五层 继续缩小为 cur = 4 cur.next = [5,6]
    // 第六层 继续缩小为 cur = 5 cur.next = [6]
    // 第七层 继续缩小为 cur = 6 cur.next = null
    // 第八层 继续缩小为 cur = null
    // 然后出栈 
    // 第八层 返回 null cur = null
    // 第七层 返回 null cur = 6 cur.next = null 返回 cur.next
    // 第六层 返回 [5] cur = 5 cur.next = null
    // 第五层 返回 [4,5] cur = 4 cur.next = [5]
    // 第四层 返回 [3,4,5] cur = 3 cur.next = [4,5]
    // 第三层 返回 [3,4,5] cur = 6 cur.next [3,4,5] 返回cur.next
    // 第二层 返回 [2,3,4,5] cur = 2 cur.next = [3,4,5]
    // 第一层 返回 [1,2,3,4,5] cur = 1 cur.next = [2,3,4,5]
    public ListNode removeElements(ListNode head, int val) {
        // 递归中止条件
        if(head == null) return null;
        // 移除一个大链表 等于判断当前 + 移除一个小链表
        head.next = removeElements(head.next,val);
        // 开始移除最小链表
        if(head.val == val){
            return head.next;
        }else{
            return head;
        }
    }
}