前言
关于移除链表元素,原题是这个样子的
PS:这个截图是截的是Leetcode的OJ题
思路:首先这个题对于删除的代码没有需要讨论的地方,需要注意的是这一句话:返回新的头节点。这就意味着如果说头结点刚好等于value或者头结点为null,那么这个返回就没有任何意义。那么这个时候就要分解决的思路了。
第一种:不设置虚拟节点
不设置虚拟节点就意味着我们需要在代码中增加判断语句,具体实现如下:
class Solution {
public ListNode removeElements(ListNode head, int val) {
//首先排除第一个节点value是val的情况
while(head != null && head.val == val){
head = head.next;
}
//然后准备进行删除
ListNode key = head;
if(key != null){//要先排除空数组的情况
while(key.next != null){//然后进行删除操作
//删除分情况讨论
if(key.next.val == val){
key.next = key.next.next;
}else{
key = key.next;
}
}
}
return head;
}
}
在这里需要增加对几种特殊输入用例的说明:假设删除value值为7的节点
输入[7,7,7,7,7]
如果输入用例是此种情况,那么其实在一开始的判断语句
while(head != null && head.val == val){
head = head.next;
}
在这一步,就会直接把head置为null,然后后面所有代码全部跳过并且返回null。
输入[]
如果输入的是空数组,那么判断语句
if(key != null){}
会阻碍它进入后续代码,所以null会直接返回。
对于[7, 1 ,2,3,4,5]
对于这种情况,代码
while(head != null && head.val == val){
head = head.next;
}
也会直接把head节点往后移,不会用7作为首节点。
第二种:设置虚拟节点
虚拟节点是比较推荐的,因为不用考虑那么多的情况。具体如下:
class Solution {
public ListNode removeElements(ListNode head, int val) {
//设置虚拟节点
ListNode header = new ListNode(21);//这里的值没有任何意义,随便设立
//然后链接head节点
header.next = head;
//定义头指针指向header
ListNode key = header;
//进行删除
while(key.next != null){
if(key.next.val == val){
key.next = key.next.next;
}else{
key = key.next;
}
}
return header.next;
}
}
为什么说这个比较推荐。
第一:不会有头结点恰好为val值然后返回无意义这种情况
第二:不用担心空数组或删除之后为空的这种情况,因为如果header.next为空会直接返回
第三种:递归
先给代码
class Solution
{
public ListNode removeElements(ListNode head, int val)
{
if (head == null)
return head;
head.next = removeElements(head.next, val);
return head.val == val ? head.next : head;
}
}
然后给图
假设输入[1,2,3,7,4,5],然后删除节点值为7的节点
就像图中说的那样,如果要删除节点值value为7的节点,那么返回head.next就好了。