题目
给你一个链表的头节点 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 输出:[]
思路一:递归
链表的定义具有递归的性质,因此链表题目常可以用递归的方法求解。这道题要求删除链表中所有节点值等于特定值的节点,可以用递归实现。
对于给定的链表,首先对除了头节点 head 以外的节点进行删除操作,然后判断 head 的节点值是否等于给定的 val。如果 head 的节点值等于 val,则 head 需要被删除,因此删除操作后的头节点为 head.next;如果 head 的节点值不等于 val,则 head 保留,因此删除操作后的头节点还是 head。上述过程是一个递归的过程。
递归的终止条件是 head 为空,此时直接返回 head。当 head 不为空时,递归地进行删除操作,然后判断 head 的节点值是否等于 val 并决定是否要删除 head。
/**
* 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){//判断头结点是否为空
return head;
}
//上述已经确认头结点不为空,我们先将除头结点的其余结点进行删除removeElements()方法可以将该链表中结点值为val的结点直接删除,且不占用多余空间
head.next = removeElements(head.next,val);
//此时我们在判断头结点的值是否为val
return head.val == val ? head.next : head;
}
}
思路二:迭代
也可以用迭代的方法删除链表中所有节点值等于特定值的节点。
用 temp 表示当前节点。如果 temp 的下一个节点不为空且下一个节点的节点值等于给定的 val,则需要删除下一个节点。删除下一个节点可以通过以下做法实现:
temp.next=temp.next.next
如果 temp 的下一个节点的节点值不等于给定的 val,则保留下一个节点,将 temp 移动到下一个节点即可。
当 temp 的下一个节点为空时,链表遍历结束,此时所有节点值等于 val 的节点都被删除。
具体实现方面,由于链表的头节点 head 有可能需要被删除,因此创建哑节点 dummyHead,令 dummyHead.next=head,初始化 temp=dummyHead,然后遍历链表进行删除操作。最终返回 dummyHead.next 即为删除操作后的头节点。
/**
* 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) {
ListNode dummyHead = new ListNode(0);//直接定义head前面的虚拟头节点,将头结点和后面所有节点一并用统一的方法来删除节点
dummyHead.next = head;//将虚拟节点放在头结点前面
ListNode temp = dummyHead;//在创建一个节点,用来删除符合条件的该节点的下一个节点
while (temp.next != null) {/循环结束的条件是刚测试指针的下一个为空,说明该指针是链表中最后一个节点,且前面所有的节点都是应该留下的
if (temp.next.val == val) {//下一个节点符合条件
temp.next = temp.next.next;//则删除
} else {//否则,直接继续进行下一个节点的检测
temp = temp.next;
}
}
return dummyHead.next;//注意返回的是虚拟节点的下一个节点
}
}