LeetCode_203. 移除链表元素及优化

427 阅读2分钟

题目

203. 移除链表元素

难度简单500

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

示例:

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

分析

image-20201223160201652

我们可以生成一个新的链表,新的链表中不包含移除的元素即可。

如上图,我们需要遍历原有的列表上的Node,如果不是要移除的结点,就添加到新链表最后一个节点的next上。

解法一

  1. 如何遍历链表

    while(head!=null){
      
      head=head.next;
    }
    
  2. 记录新链表的head和新链表的最后一个节点的位置

    ListNode newHead=null;
    ListNode currentNode=null;
    
  3. 如果变量到的结点不是要移除的结点,就将他添加到新链表上。然后移动currentNode指向最后一个节点。

    if(head.val!=val){
      currentNode.next=head;
      currentNode=head;
    }
    
  4. 最后需要注意将最后一个节点的next设置为null,来结束当前链表。

    currentNode.next=null;
    

下面是全部的代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode removeElements(ListNode head, int val) {
       if (head == null) return null;
        //记录新链表的头
        ListNode newHead = null;
        //记录当前扫描到的Node位置
        ListNode currentNode = null;
        while (head != null) {
            if (val != head.val) {
                if (currentNode == null) {
                  	//生成新链表头
                    newHead = head;
                    //记录新Node的位置
                    currentNode = head;
                } else {
                    //链表上添加新Node
                    currentNode.next = head;
                    //记录新Node的位置
                    currentNode = head;
                }
            }

            head = head.next;
        }

        //注意空指针
        if (currentNode == null) {
            return null;
        } else {
            //结束链表,currentNode就是链表的尾部
            currentNode.next = null;
        }
        return newHead;
    }
}

提交结果:

image-20201223153452309

解法二

使用虚拟节点,减少判断。

直接新建一个节点作为虚拟节点VNode,如果有符合条件的Node,直接添加到该VNode的next上。

最后返回的新链表的head,其实就是虚拟节点的next位置的Node。

这样我们就不必判断头节点是否为空。

 /**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        if (head == null) return null;
        //虚拟节点
        ListNode vNode = new ListNode(0);
 				//记录当前扫描到的Node位置
        ListNode currentNodex = vNode;

        while (head != null) {
            if (val != head.val) {
                currentNodex.next = head;
                currentNodex = head;
            }
            head = head.next;
        }
        currentNodex.next = null;
        //虚拟节点的next就是新链表的head
        return vNode.next;

    }
}

效率上应该没有什么提升,只是间接了思路。

image-20201223154149849