203.移除链表元素

解法1:虚拟节点法

   ListNode virtualnode=new ListNode(val-1);
        virtualnode.next=head;//设置虚拟节点,为本题关键,为了处理如果头节点需要删除的情况
        ListNode tmp=virtualnode;
        while(tmp.next!=null) {
            if(tmp.next.val==val) {//一旦下一个节点val相等
                tmp.next=tmp.next.next;//移除下一个节点
            }
            else {
                tmp=tmp.next;
            }

        }
        return virtualnode.next;//注意,是返回.next,因为第一个节点是虚拟节点。而返回virtualnode而不是tmp的原因是,两者所拥有的各节点完全相同

思路简述

本题的关键就是虚拟节点的应用,虚拟节点的设置,就是为了处理头节点需要被删除时的情况。然后一次遍历,看此时节点的下一个节点是否需要删除。⚠️,是判断下一个节点!
而返回virtualnode而不是tmp的原因是,两者所拥有的各节点完全相同,而不是tmp复制virtualnode节点的关系,两者本质上是一个链表。区别在于此时指向哪一个节点,比如在最后return的时候,virtualnode指向开头的虚拟节点,而tmp经过遍历已经指向了最后一个节点。所以应该是返回virtualnode的下一个节点,真正的头节点。
本题感悟,要对链表的存储有着深刻的认识,链表上各个节点都是各自流浪在内存的不同位置。地理位置上本并没有什么关系,是指针强行将它们联系起来,但是本质上各节点是独立的个体。

解法2:递归法

public ListNode removelistelement(ListNode head,int val) {
            if(head==null) {
             return null;    
         }
         head.next=removelistelement(head.next,val);
         if(head.val==val)
             return head.next;
         else
             return head;
     }

思路简述

主要思路就是先“递”到最后的null节点,然后head.next=null,首先到达了尾节点,然后判断此时的尾节点的值是否等于val,从而判断是否删除当前的节点,如果删除,就返回当前节点的下一个节点。否则,就返回当前节点。重复上面的步骤,依次“归”,直到回到第一个节点。很巧妙的递归方法。

19.删除链表的倒数第N个结点

public ListNode removeNthfromEnd(ListNode head,int n) {

      ListNode virtualnode=new ListNode(0);//设置虚拟节点,解决头节点被删除问题
        virtualnode.next=head;
        ListNode fast=virtualnode;
        ListNode slow=virtualnode;
        while(n!=0) {
            fast=fast.next;    
                        n--;
        }//上面这个循环是让快指针先走n步
        while(fast.next!=null) {//直到快指针走到尾节点,那么慢指针走的步数等于总节点数m-1-n,到达第m-n个节点。倒数第n个数字,就是正数第m-n+1个节点;所以要删除此时slow后面的节点
            fast=fast.next;
            slow=slow.next;//快慢指针同时前进
        }
        slow.next=slow.next.next;//删除慢节点后面的节点,也就是倒数第n个节点
        return virtualnode.next;
}

思路简述

关键点在于快慢指针的设置,先让快指针先走n步。直到快指针走到尾节点,那么慢指针走的步数等于总节点数m-1-n,也就是到达第m-n个节点。而倒数第n个数字,就是正数第m-n+1个节点;所以要删除此时slow后面的节点。最后返回virtualnode.next.


leetcode      链表 双指针 虚拟节点

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!