LeetCode [203. 移除链表元素]
题目:给你一个链表的头节点 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) {
/*
*删除头结点,头结点存在且头结点的值等于val时
*将新的头结点设置为head.next(头结点向后移动一位)并删除原来的头结点(Java自带回收机制,不需要手动清除)
*/
while(head != null && head.val == val){
head = head.next;
}
/*
*head已经为null,提前退出,返回结果
*/
if(head == null){
return head;
}
/*
*删除非头节点
*在"下个节点1"存在的情况下
*如果"下个节点1"的值等于目标值,删除"下个节点1"(方式是当前节点的next指向"下个节点1"的"下个节点2")
*如果"下个节点1"的值不等于目标值,则将"当前节点"移动到"下个节点1",保留"下个节点1"
*将pre和cur移动到下一个节点
*"当前节点"的下一个节点为空时,链表遍历结束,此时所有节点值等于val的节点都被删除。
*/
ListNode pre = head;
ListNode cur = head.next;
while(cur != null){
if(cur.val == val){
pre.next = cur.next;
}else{
pre = cur;
}
cur = cur.next;
}
return head;
}
}
//添加一个虚拟头结点法
class Solution {
public ListNode removeElements(ListNode head, int val) {
if