1. 程式人生 > 實用技巧 >《劍指offer》 —— 連結串列中倒數第k個節點

《劍指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老師的前端補習班」關注我的微信公眾號,那麼就可以第一時間收到我的最新文章。