Leetcode No.203
级别:easy
删除链表中等于给定值 val 的所有节点。
示例:
输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5
普通
- head.val == val 直接将 head = head.next, 将头节点断开删除
- head.val == null 已经是空链表,无需下面操作
- head.val != val
定义一个mPrev = head,用来遍历后面的数据
(1) mPrev .next.val == val
将mPrev .next == mPrev .next.next,断开mPrev .next
(2) mPrev .next.val != val
mPrev = mPrev.next 继续循环遍历下一个数据,重复操作
返回 head
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
//如果head 的val == val,头节点处理
while (head != null && head.val == val) {
ListNode mListNode = head;
head = head.next;
mListNode = null;
}
//头节点为空,此时返回
if (head == null) {
return null;
}
//通过循环,比较mPrev.next.val 的值,
//如果==val,则将mPrev.next 指向 mPrev.next.next
//否则继续遍历,知道空为止
ListNode mPrev = head;
while (mPrev.next!= null) {
if (mPrev.next.val == val) {
ListNode mNode = mPrev.next;
mPrev.next = mNode.next;
mNode.next = null;
} else {
mPrev = mPrev.next;
}
}
return head;
}
}
虚拟节点
添加虚拟节点的好处是,省略了第一种方法中对head节点的单独判断。
其他逻辑与第一种方法相同。
注意此时返回的是:mDumHead.next
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode mDumHead = new ListNode(-1);
mDumHead.next = head;
ListNode mPrev = mDumHead;
while (mPrev.next != null) {
if (mPrev.next.val == val) {
ListNode mNode = mPrev.next;
mPrev.next = mNode.next;
mNode.next = null;
} else {
mPrev = mPrev.next;
}
}
return mDumHead.next;
}
}
递归
思路:大问题规划成小问题
removeElements 的宏定义:
1. head == null 头节点为空时,返回null,无需下面操作
2. head.val == val 返回head.next(递归后的值)
3. head.val != val 返回head
class Solution {
public ListNode removeElements(ListNode head, int val) {
if (head == null) {
return null;
}
head.next = removeElements(head.next, val);
return head.val == val ? head.next : head;
}
}