《剑指offer》 —— 链表中倒数第k个节点

点击查看原文
点击查看原题

题目

输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。

解题思路

递归法

这应该是最直观的方法:
递归到链表结束,回溯到时候开始计数,直到 k === 0 时,取当前的 head 节点。

代码

/**
 * @param {ListNode} head
 * @param {number} k
 * @return {ListNode}
 */
var getKthFromEnd = function(head, k) {
    const helper = (head) => {
        if (!head) {
            return
        }
        helper(head.next)
        if (--k === 0) {
            res = head
        }
    }
    let res = null
    helper(head)
    return res
};

直接遍历法

遍历拿到链表的长度 (N),倒数第 (k) 个节点就是第 (N - k) 个节点。

代码

/**
 * @param {ListNode} head
 * @param {number} k
 * @return {ListNode}
 */
var getKthFromEnd = function(head, k) {
    const getListLength = (head) => {
        if (!head) {
            return 0
        }
        let fast = head.next
        let count = 0
        while (fast && fast.next) {
            count++
            fast = fast.next.next
        }
        return fast ? 2 * count : 2 * count + 1
    }
    const N = getListLength(head)
    for (let i = N - k; i > 0; i--) {
        head = head.next
    }
    return head
};

双指针法

设置快慢指针,其中 fast 先走 (k) 步,然后 slowfast 一起走,直到 fast 为空时,slow 就走了 (N - k) 步,此时 slow 指向倒数第 (k) 个节点。

/**
 * @param {ListNode} head
 * @param {number} k
 * @return {ListNode}
 */
var getKthFromEnd = function(head, k) {
    let slow = head
    let fast = head
    while (k) {
        fast = fast.next
        k--
    }
    while (fast) {
        slow = slow.next
        fast = fast.next
    }
    return slow
};

搜索「tony老师的前端补习班」关注我的微信公众号,那么就可以第一时间收到我的最新文章。

原文地址:https://www.cnblogs.com/pigpigever/p/13695431.html