[路飞]_算法成长之路九,删除链表的倒数第 N 个结点

104 阅读2分钟

个人算法成长之路九!!!定期更新一些刷题过程中个人的思路以及理解。有兴趣的朋友们可以互动交流哈~

题目:

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

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

示例 1:

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

示例 2:

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

示例 3:

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

解题思路:

解题思路

分析题目,我们很容易的可以得到暴力解法,先遍历一遍链表得到链表总长度, 然后用总长度减去 n,我们很快就得到了要删除目标节点的 下标,然后就是移动指针到目标节点的前一个节点直接删除即可。 但这不满足进阶要求, 要满足进阶要求, 本题目还是采用快慢指针来解决。

根据题目特征有删除的目标节点始终在末尾前n位。

具体流程

1.我们可以设置一个快指针和一个慢指针同时指向头节点,让快指针先走n个节点。

2.然后让慢指针和快指针同时开始,直到快指针遍历结束。

3.让慢指针的next指针指向慢指针的next所指向的next。

4.返回头节点。

注意:题目虽然很友好的不让 n 超过链表长度,但是它有可能等于链表长度, 因此当n == 链表长度时候需要特殊处理。

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} n
 * @return {ListNode}
 */
var removeNthFromEnd = function(head, n) {
    let fast = head, slow = head;
    for(let i = 0; i < n; i++) {
        fast = fast.next;
    }
    if(!fast)
        return head.next; // 处理 n等于链表长度的异常。
    while(fast.next != null) {
        fast = fast.next;
        slow = slow.next;
    }
    slow.next = slow.next.next;
    return head;
};