来一起刷简单算法题[十] 链表

166 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第17天,点击查看活动详情

删除链表中的第N个节点

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

输入: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

进阶:你能尝试使用一趟扫描实现吗?

/**
 * 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) {
    
};

非递归解法

  1. 求出链表的长度
  2. 长度减去n,得到目标下标
  3. 循环到目标下标 - 1,拿到目标下标上一个即可
/**
 * 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}
 */
// 求链表的长度
const length = (head) => {
    let count = 0;
    while(head !== null) {
        count++
        head = head.next
    }
    return count
}
var removeNthFromEnd = function(head, n) {
    // 求出下标的位置
    const last = length(head) - n
    if (last === 0) {
        // 要删除的是第一个节点
        head = head.next
    } else {
        let current = head
        // 获取n的前一个,所以要减1
        for (let i = 0; i < last - 1; i++) {
            current = current.next
        }
        current.next = current.next.next
    }
    return head
};

双指针法

上面是先计算链表的长度,其实不计算链表的长度也是可以,我们可以使用两个指针,一个指针fast先走n步,然后另一个指针slow从头结点开始,找到要删除结点的前一个结点,这样就可以完成结点的删除了。

/**
 * 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 === null) {
        // 表示删的是头节点
        return head.next
    }
    while(fast.next !== null) {
        fast = fast.next
        slow = slow.next
    }
    slow.next = slow.next.next
    return head
};