移除列表元素

179 阅读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 <= k <= 50

情况分析: 1)该链表中只有一个head节点,此时直接返回输出"[ ]" 2)要删除的节点在中间,且它的下一个不是目标删除的元素(直接将prev的next指向其下一个元素的next域) 3)要删除的节点在中间,且它的下一个也是需要删除的(此时将不能就直接更改,因为可能会出现它的下一个还是的情况) 综合2)3)点,此时设置两个指针,prev和del,当找到第一个目标时,让del先向下继续扫描看是不是要删除的元素,①是,继续向下判断 ②不是,就让prev.next = del.next; 4)再分析一下如果是最后一个元素,是否被以上两种情况包含,根据以上情况,能够将最后一个元素删除,不需要考虑 5)再分析第一个如果为要删除的元素,发现:第一个元素删不掉,需要处理这个head,①将它放在最后进行删除,先从第二个开始 ②先从头节点开始向后删,直到第一个出现不为目标节点的节点,让它成为新的头节点 ③在头节点之前建立一个虚拟头节点,使之可以从头来进行删除,最后返回这个节点。 6)返回 ListNode类型

情况一:

image.png 情况二:

image.png 情况三:

image.png


/**
* 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) {
                //判断头节点本身是否存在
        if (head == null) {
            System.out.println("该链表没有任何节点");
            return null;
        }
        //设置指针,向后扫描
        ListNode prev = head;


        while (prev.next != null) {
            if(prev.next.val == val) {
                prev.next = prev.next.next;
            }else {
                prev = prev.next;




            }
        }

        //最后处理头节点
        if(head.val == val) {
            head = head.next;
        }
        return head;
    }
}

其他思路:
第一种:先处理头节点

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        //删除目标头结点后,可能新的头结点的值也相等,用循环来判断,知道出现第一个不等于val的新的头节点
        while(head!=null&&head.val==val){
            head=head.next;
        }

        if(head==null) {
            return head;
        }
        ListNode prev=head;
        //确保当前结点后还有结点
        while(prev.next!=null){
            if(prev.next.val==val){
                prev.next=prev.next.next;
            }else{
                prev=prev.next;
            }
        }
        return head;
    }
}

第二种:虚拟头节点

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        //创建一个虚拟头结点
        ListNode dummyNode=new ListNode(val-1);
        dummyNode.next=head;
        ListNode prev=dummyNode;
        //确保当前结点后还有结点
        while(prev.next!=null){
            if(prev.next.val==val){
                prev.next=prev.next.next;
            }else{
                prev=prev.next;
            }
        }
        return dummyNode.next;
    }
}