leetcode刷题之链表之移除元素

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.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值