📑 题目:19. 删除链表的倒数第 N 个结点

🚀 本题 LeetCode 传送门

题目大意

删除链表中倒数第 n 个结点。

解题思路

这道题比较简单,先循环一次拿到链表的总长度,然后循环到要删除的结点的前一个结点开始删除操作。需要注意的一个特例是,有可能要删除头结点,要单独处理。

这道题有一种特别简单的解法。设置 2 个指针,一个指针距离前一个指针 n 个距离。同时移动 2 个指针,2 个指针都移动相同的距离。当一个指针移动到了终点,那么前一个指针就是倒数第 n 个节点了。

代码

  1. package leetcode
  2. import (
  3. ""github.com/halfrost/LeetCode-Go/structures""
  4. )
  5. // ListNode define
  6. type ListNode = structures.ListNode
  7. /**
  8. * Definition for singly-linked list.
  9. * type ListNode struct {
  10. * Val int
  11. * Next *ListNode
  12. * }
  13. */
  14. // 解法一
  15. func removeNthFromEnd(head *ListNode, n int) *ListNode {
  16. dummyHead := &ListNode{Next: head}
  17. preSlow, slow, fast := dummyHead, head, head
  18. for fast != nil {
  19. if n <= 0 {
  20. preSlow = slow
  21. slow = slow.Next
  22. }
  23. n--
  24. fast = fast.Next
  25. }
  26. preSlow.Next = slow.Next
  27. return dummyHead.Next
  28. }
  29. // 解法二
  30. func removeNthFromEnd1(head *ListNode, n int) *ListNode {
  31. if head == nil {
  32. return nil
  33. }
  34. if n <= 0 {
  35. return head
  36. }
  37. current := head
  38. len := 0
  39. for current != nil {
  40. len++
  41. current = current.Next
  42. }
  43. if n > len {
  44. return head
  45. }
  46. if n == len {
  47. current := head
  48. head = head.Next
  49. current.Next = nil
  50. return head
  51. }
  52. current = head
  53. i := 0
  54. for current != nil {
  55. if i == len-n-1 {
  56. deleteNode := current.Next
  57. current.Next = current.Next.Next
  58. deleteNode.Next = nil
  59. break
  60. }
  61. i++
  62. current = current.Next
  63. }
  64. return head
  65. }