[路飞]_程序员必刷力扣题: 19. 删除链表的倒数第 N 个结点

403 阅读2分钟

「这是我参与12月更文挑战的第19天,活动详情查看:2021最后一次更文挑战

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

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

示例 1: image.png

输入: head = [1,2,3,4,5], n = 2
输出: [1,2,3,5]

示例 2:

输入: head = [1], n = 1
输出: []

示例 3:

输入: head = [1,2], n = 1
输出: [1]

提示:

  • 链表中结点的数目为 sz
  • 1 <= sz <= 30
  • 0 <= Node.val <= 100
  • 1 <= n <= sz   进阶: 你能尝试使用一趟扫描实现吗?

递归

思路

使用递归的思想: 这里我们定义了三个变量,

  • pre用来保存删除节点的前一个节点,

  • next用来保存删除节点的下一个节点,

  • index用来记录当前是倒数第几个节点

最后进行判断,如果存在pre证明不是删除第一个节点,先处理pre.next = next 然后返回头节点head

如果pre不存在证明删除的是头节点,直接返回head.next

var removeNthFromEnd = function (head, n) {
    var pre = null
    var next = null
    var index = 0
    function remove(head, n) {
        if (!head) {
            index++
            return
        }
        remove(head.next, n)
        
        if (index === n) {
            next = head.next
        }
        if (index === n + 1) {
            pre = head
        }
        index += 1
    }
    remove(head, n)

    if (pre) {
        pre.next = next
        return head
    } else {
        return head.next
    }
};

哈希表思路

思路

这里我们用数组来保存我们遍历链表的每一个节点得到数组arr

同上寻找pre节点以及next节点

  • 需要删除的n节点的下标为arr.leng-n

  • 所以pre节点的下标为arr.length-n-1

  • next节点的下标为arr.length-n+1

这里需要注意的是找到pre和next后再去删除n节点,因为提前删除n节点会影响寻找pre和next的下标,导致错误,所以放在最后删除

最后看数组中是否还有值,有就直接返回第一个节点,否则就返回null

var removeNthFromEnd = function (head, n) {
    var pre = null
    var next = null
    var arr = []
    while (head) {
        arr.push(head)
        head = head.next
    }
    if (arr[arr.length - n + 1]) {
        next = arr[arr.length - n + 1]
    }
    if (arr[arr.length - n - 1]) {
        pre = arr[arr.length - n - 1]
        pre.next = next
    }
    arr.splice(arr.length - n, 1)
    var res = arr[0] ? arr[0] : null
    return res

};