这篇有四道类似题目
203. 移除链表元素 public ListNode removeElements(ListNode head, int val) {
237. 删除链表中的节点 public void deleteNode(ListNode node) {
面试题 02.03. 删除中间节点 public void deleteNode(ListNode node) {
剑指 Offer 18. 删除链表的节点 public ListNode deleteNode(ListNode head, int val) {
237和m0203 基本一致
237强调了所有值唯一 且不为尾结点
无返回
- 因为要直接删除
- 但是没有指向前一节点的指针
- 只能将node的next的值 赋给node
- 然后让node的next指向 next的next
- 意味着 直接用原本的node next替代 node
- 再把node next删掉
- 无返回
public void deleteNode(ListNode node) {// 传入要删除的节点
node.val = node.next.val;
node.next = node.next.next;
}
203和J18 基本一致
传入参数为 头节点head 和要删除的值val
J18强调了所有值唯一
要求返回节点
- 定义哨兵节点sentinel,让链表标准化,如使链表永不为空、永不无头、简化插入和删除。
- ListNode sentinel = new ListNode(0);
- sentinel.next = head;
- 定义curr节点指向head
- 定义prev节点指向sentinel
- 如果curr不为空
- 如果curr的值不是val,就curr和prev向后移一个
- 如果curr的值是val,就prev指向curr的next,curr后移一个
- 直到curr为空结束循环 删掉了所有val值的节点
- 返回sentinel.next
public ListNode deleteNode2(ListNode head, int val) {// 传入头节点和要删除的数值
//定义哨兵节点,目的是使链表标准化,如使链表永不为空、永不无头、简化插入和删除。
ListNode sentinel = new ListNode(0);
sentinel.next = head;
//初始化两个指针 slow指向前驱节点 fast指向头节点
ListNode slow = sentinel;
ListNode fast = head;
while (fast != null) {//当前节点不为空
if (fast.val == val) //当前节点就是要删除的节点
slow.next = fast.next;//跳过当前节点
else slow = fast;
fast = fast.next;//遍历下一个元素
}
return sentinel.next;//返回哨兵指向的next 即head
}