LeetCode - 203.移除链表元素

题目描述

删除链表中等于给定值 val 的所有节点。

示例:

输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5

完整代码参考:GitHub 代码

题解

此题难度定级为简单,主要考察链表的基本操作。

解法1:双指针

思路:构造双指针指向同一链表,一个用来读链表(temp),一个用来删除链表元素(cur)。

算法:由于待删除元素可能为首节点,故需要先构建一个临时节点,在其后拼接原链表。然后,再构造一个指针指向拼接后链表的首节点,用来操作链表删除元素。遍历链表,对符合条件的元素删除(cur.next = cur.next.next 即改变 cur.next 的指向,删除 cur.next 节点)。结束后返回 temp 指向的下一个节点及其后的链表部分。

    public ListNode removeElements(ListNode head, int val) {
        // 构造临时节点。(用来读取链表)
        ListNode temp = new ListNode(-1);
        // 临时节点之后拼接原链表。由于可能删除的节点是首节点,所以在原链表之前先拼接一个临时节点。
        temp.next = head;
        // 再构造一个指针指向同一链表的首节点。(用来操作链表)
        ListNode cur = temp;

        // 由于需要移动节点,所以比较 cur.next 节点。
        while (cur.next != null) {
            if (cur.next.data == val) {
                // 删除 cur.next 元素。改变 cur.next 的指向。
                cur.next = cur.next.next;
            } else {
                // 移动下一个节点
                cur = cur.next;
            }
        }
        // 返回临时节点后的链表
        return temp.next;
    }

解法2:数组中转,构造新链表

思路:链表数据转存数组,再构建新的链表。

算法:遍历链表,将数值存储于数组中,当 list 不为空时,以第一个元素构造首节点,在其后构造余下节点。

    public ListNode removeElements(ListNode head, int val) {
        if (head == null) {
            return null;
        }

        // 筛选 list
        List<Integer> list = new ArrayList<>();
        while (head != null) {
            if (head.data != val) {
                list.add(head.data);
            }
            head = head.next;
        }

        // 防止 get(0) 异常
        if (list.isEmpty()) {
            return null;
        }

        // 构造结果链表
        ListNode result = new ListNode(list.get(0));
        for (int i = 1; i < list.size(); i++) {
            addListNodeFromLast(result, list.get(i));
        }
        return result;
    }

    public static ListNode addListNodeFromLast(ListNode head, int num) {
        // 新建节点
        ListNode newNode = new ListNode(num);
        // 头节点为空时直接将新建的节点设置为头节点
        if (head == null) {
            head = newNode;
        } else {
            // 遍历需要一个额外的存储空间存储当前节点,找到尾节点
            ListNode temp = head;
            // 头节点非空,遍历节点
            while (temp.next != null) {
                // 节点后移
                temp = temp.next;
            }
            // 把当前节点设置为尾节点
            temp.next = newNode;
        }
        return head;
    }

 

©️2020 CSDN 皮肤主题: 精致技术 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值