Lever's Castle

19. 删除链表的倒数第N个节点

February 18, 2020

https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/

使用语言:Golang

解:

    /**
     * Definition for singly-linked list.
     * type ListNode struct {
     *     Val int
     *     Next *ListNode
     * }
     */
    func removeNthFromEnd(head *ListNode, n int) *ListNode {
        var nodes []*ListNode
        cur := head
        for cur != nil {
            nodes = append(nodes, cur)
            cur = cur.Next
        }
        removedHeadIndex := len(nodes) - n
        if removedHeadIndex == 0 {
            if removedHeadIndex + 1 < len(nodes) {
                return nodes[removedHeadIndex + 1]
            }
            return nil
        }
        if removedHeadIndex + 1 >= len(nodes) {
            nodes[removedHeadIndex - 1].Next = nil
        } else {
            nodes[removedHeadIndex - 1].Next = nodes[removedHeadIndex + 1]
        }
        
        return head
    }

思路

可以先简化下问题,题目中要删除的是从最后一个开始数的第 N 个元素。那如果我们能够知道这个链表的长度,就很容易能算出这个待删除元素的正向索引。找到了这个元素,我们实际上要做的是把他的前一个元素和后一个元素关联起来。所以我们还需要知道这个元素的上一个元素和下一个元素。对链表来讲,下一个元素很好拿到,但是上一个元素就不太好拿了。而且我们并不知道这个链表的长度,因此如果要只遍历一次就找到这个元素,我决定先把链表转成比较好操作的数组。这样之后的操作全部都是 O(1) 的索引操作了。

需要注意的是,在处理这个数组的待删除元素时,有很多边界情况需要考虑:

  • 被删除的是第一个元素,需要这个元素后边的链表返回去。如果后边没有链表,需要返回 nil
  • 被删除的是最后一个元素,则前一个元素需要将 Next 置为 nil
  • 被删除的是中间某个元素,则直接将前一个元素的 Next 置为后一个元素

Lever

痕迹
没有过去,就没法认定现在的自己