Notes
← All notes
·frontend·12 min

LeetCode Cycle 05:Linked List 的面試重點與 DOM / LRU 連結

Linked List 在演算法面試永遠在問 dummy head、反轉、cycle 偵測這三件事,但前端面試的加分題是「DOM tree 的 sibling 串就是 doubly linked list」「LRU cache 為什麼一定要 doubly linked list + hash」這類連結。內部使用。

#leetcode#algorithm#linked-list#floyd-cycle#lru#dom#interview-prep#面試系列#private

寫前端寫到第七年都還沒有真的「自己宣告一個 linked list」過——所有的列表結構不是 array 就是 Map。但 senior 面試一定會考 linked list,理由不是要你會手寫,是要你知道「指標操作」這條心智模型——因為 DOM 樹的 sibling navigation 就是 linked list[^1]、React Fiber 內部也是 linked list、瀏覽器 LRU cache 跟 React Query 的 query cache 都是 doubly linked list + hash map 的組合。Cycle 05 的題型本質是「在不能用 array index 的世界裡,你怎麼操作元素」。

Linked list 的底層心智模型

class ListNode {
  constructor(val = 0, next = null) {
    this.val = val;
    this.next = next;
  }
}

跟 array 的差別:

操作ArraySingly Linked List
隨機存取 arr[k]O(1)O(k),要從 head 走
開頭插入 / 刪除O(n)O(1)
中間插入 / 刪除(已有指標)O(n)O(1)
中間插入 / 刪除(沒有指標)O(n)O(n)
找特定 valueO(n)O(n)

同樣是「中間插入/刪除」,為什麼會分出 O(1) 跟 O(n) 兩種結果?把成本拆成「找到節點」跟「改指標」兩段就一目了然:

前提找到節點改指標總成本
已有指標O(1),reference 已經在手O(1)O(1)
沒有指標(只給第 k 個位置)O(k),最差 O(n),要從 head 走 k 步O(1)O(n)

關鍵在「改指標」永遠是 O(1)——差別全出在「找到節點」那一欄。

表格裡的 「已有指標」 指你手上已經拿到「要操作位置的那個節點」的 reference——例如 callback 把節點傳給你、或剛 traverse 到那一格。在這個前提下,刪除/插入就只是改 node.next = X 一行,所以是 O(1)。

如果沒有指標——只給「第 k 個位置」這種抽象描述——必須先從 head 一步一步走 k 步找到節點,這段是 O(k),最差 O(n),整個中間操作就退化成 O(n),跟 array 一樣。所以 linked list 的 O(1) 不是免費的,要先付出「能取得指標」的代價。

這個前提解釋了後面 §LRU Cache 為什麼一定要 doubly linked list + hash map 的組合:hash map 用 key 直接 O(1) 拿到節點 reference,doubly linked list 才有條件 O(1) 把節點移到 head、從 tail 移除。少了 hash map,光找節點就 O(n),再快的 list 操作也救不回來。