我们一起学习删除链表的节点

时间:2022-06-10 14:28:04

我们一起学习删除链表的节点

本文转载自微信公众号「程序员千羽」,作者程序员千羽。转载本文请联系J程序员千羽公众号。

Leetcode : https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof

“GitHub : https://gitee.com/nateshao/leetcode/blob/main/algo-notes/src/main/java/com/nateshao/sword_offer/topic_12_hammingWeight/Solution.java

删除链表的节点

“题目描述: 给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。返回删除后的链表的头节点。示例 1:

  1. 输入: head = [4,5,1,9], val = 5
  2. 输出: [4,1,9]
  3. 解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.

示例 2:

  1. 输入: head = [4,5,1,9], val = 1
  2. 输出: [4,5,9]
  3. 解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.

解题思路:

本题删除值为 val 的节点分需为两步:定位节点、修改引用。

  • 定位节点: 遍历链表,直到 head.val == val 时跳出,即可定位目标节点。
  • 修改引用: 设节点 cur 的前驱节点为 pre ,后继节点为 cur.next ;则执行 pre.next = cur.next ,即可实现删除 cur 节点。

我们一起学习删除链表的节点

** 算法流程:**

  • 特例处理: 当应删除头节点 head 时,直接返回 head.next 即可。
  • 初始化: pre = head , cur = head.next 。
  • 定位节点: 当 cur 为空 或 cur 节点值等于 val 时跳出。
    • 保存当前节点索引,即 pre = cur 。
    • 遍历下一节点,即 cur = cur.next 。
  • 删除节点: 若 cur 指向某节点,则执行 pre.next = cur.next ;若 cur 指向 nullnull ,代表链表中不包含值为 val 的节点。
  • 返回值: 返回链表头部节点 head 即可。

我们一起学习删除链表的节点

复杂度分析:

  • 时间复杂度 O(N): N为链表长度,删除操作平均需循环 N/2 次,最差 N 次。
  • 空间复杂度 O(1) : cur, pre 占用常数大小额外空间。
  1. package com.nateshao.sword_offer.topic_15_deleteNode;
  2.  
  3. /**
  4. * @date Created by 邵桐杰 on 2021/11/21 16:22
  5. * @微信公众号 程序员千羽
  6. * @个人网站 www.nateshao.cn
  7. * @博客 https://nateshao.gitee.io
  8. * @GitHub https://github.com/nateshao
  9. * @Gitee https://gitee.com/nateshao
  10. * Description: 删除链表的节点
  11. */
  12. public class Solution {
  13. public static void main(String[] args) {
  14. ListNode listNode = new ListNode(3);
  15. int val = 3;
  16. ListNode node = deleteNode(listNode, val);
  17. System.out.println("node = " + node);
  18. }
  19. // 推荐
  20. public static ListNode deleteNode(ListNode head, int val) {
  21. if (head.val == val) return head.next;
  22. ListNode pre = head, cur = head.next;
  23. while (cur != null && cur.val != val) {
  24. pre = cur;
  25. cur = cur.next;
  26. }
  27. if (cur != null) pre.next = cur.next;
  28. return head;
  29. }
  30.  
  31. public void deleteNode(ListNode head, ListNode deListNode) {
  32. if (deListNode == null || head == null)
  33. return;
  34. if (head == deListNode) {
  35. head = null;
  36. } else {
  37. // 若删除节点是末尾节点,往后移一个
  38. if (deListNode.next == null) {
  39. ListNode pointListNode = head;
  40. while (pointListNode.next.next != null) {
  41. pointListNode = pointListNode.next;
  42. }
  43. pointListNode.next = null;
  44. } else {
  45. deListNode.val = deListNode.next.val;
  46. deListNode.next = deListNode.next.next;
  47. }
  48. }
  49. }
  50.  
  51. /**
  52. * 单指针实现
  53. *
  54. * @param head
  55. * @param val
  56. * @return
  57. */
  58. public ListNode deleteNode2(ListNode head, int val) {
  59. if (head == null) return null;
  60. if (head.val == val) return head.next;
  61. ListNode cur = head;
  62. while (cur.next != null && cur.next.val != val) {
  63. cur = cur.next;
  64. }
  65. if (cur.next != null) {
  66. cur.next = cur.next.next;
  67. }
  68. return head;
  69. }
  70.  
  71. /**
  72. * 递归实现
  73. *
  74. * @param head
  75. * @param val
  76. * @return
  77. */
  78. public ListNode deleteNode3(ListNode head, int val) {
  79. if (head == null) return null;
  80. if (head.val == val) return head.next;
  81. else head.next = deleteNode3(head.next, val);
  82. return head;
  83. }
  84.  
  85. public static class ListNode {
  86. int val;
  87. ListNode next;
  88.  
  89. ListNode(int x) {
  90. val = x;
  91. }
  92. }
  93. }

参考链接:https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/solution/mian-shi-ti-18-shan-chu-lian-biao-de-jie-dian-sh-2

原文地址:https://mp.weixin.qq.com/s/jTI1x9JAk0WEPbDRFdt07w