链表系列① -- 移除链表元素

举报
十八岁讨厌编程 发表于 2022/08/06 00:42:04 2022/08/06
【摘要】 文章目录 题目概述解题思路方法一方法二 代码实现小总结注意点①:返回值注意点②:空指针 题目概述 对应力扣203.移除链表元素 给你一个链表的头节点 head 和一个整数 ...

题目概述

对应力扣203.移除链表元素

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
示例:
在这里插入图片描述

解题思路

移除链表中的元素有两种方法:

  • 创建一个虚拟的头节点
  • 直接使用原来的链表来进行删除操作

这两种方法无论使用哪一种,都要借助双指针进行

方法一

创建一个虚拟头节点之后,将其next指向现在的head节点。设置快慢指针(我们规定pre表示快指针,cur表示慢指针),将pre指向虚拟头节点,将cur指向head节点。如果cur不为null就可以一直往后移动。在移动的途中比对cur中存储的数据是否符合删除的情况。

如果符合删除的情况,则将pre的next指向cur的next域,如此就相当于把cur指向的节点从这个链表中拆了下来。这之后一定要记得把cur向后移一位

在这里插入图片描述

在这里插入图片描述
如果不符合删除的情况,则直接将cur和pre指针向后移一位即可。

方法二

首先我们要单独讨论删除头节点的情况。操作也非常简单,将head向后移一位即可
在这里插入图片描述
在这里插入图片描述
然后其余的情况与方法一类似,创建两个指针pre,cur。pre指针指向head,cur指针指向head.next。具体的删除步骤与方法一相同。

代码实现

方法一

public ListNode removeElements1(ListNode head, int val) {
		ListNode xuni = new ListNode(-1,head);
		ListNode pre = xuni;
		ListNode cur = xuni.next;
		while(cur != null) {
			if(cur.val == val) {
				pre.next = cur.next;
			}else {
				pre = pre.next;
			}
			//不管是否删除了,都要将cur指针向后移一个
			cur = cur.next;
		}
		return xuni.next;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

方法二

public ListNode removeElements2(ListNode head, int val) {
			//如果要删除头节点
			while(head != null && head.val == val) head = head.next;
			if(head == null) return head;
			ListNode cur = head.next;
			ListNode pre = head;
			while(cur != null) {
				if(cur.val == val) pre.next = cur.next;
				else pre = pre.next; 
				cur = cur.next;
			}
			return head;
    }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

小总结

移除链表中的元素有两个需要注意的点:

注意点①:返回值

在方法二中直接return head无可厚非,但是在方法一中:

return xuni.next;

  
 
  • 1

这个地方极易发生错误,容易错写成:

return head

  
 
  • 1

或者

return pre.next

  
 
  • 1

那么这两个为什么不行呢?
return head不行是因为这个head节点可能已经被删除了,那么再返回它也就没有意义了。return pre.next不行是因为,此时你的pre指针已经到链表的末尾去了,你返回压根得不到什么东西。

注意点②:空指针

可以注意到我在方法二中多了这么一行代码:

if(head == null) return head;

  
 
  • 1

这行代码在方法一中是没有的。这句话非常重要,并不是可有可无。
在方法二中如果给的是一个空链表,或者删除后成为了空列表,那么head就成为了一个空指针,而后面的head.next也就毫无意义了。方法一中不用加这句话是因为有一个虚拟头节点他是永远不会被删掉的,所以后面也就不会出现空指针报错的问题。

文章来源: blog.csdn.net,作者:十八岁讨厌编程,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/zyb18507175502/article/details/123312069

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。