題目描述:
設計一個樹狀結構的鎖定系統 LockingTree。給定一棵以節點 0 為根的樹(用 parent 陣列表示),支援三種操作:
lock(num, user):若節點 num 未被鎖定,則由 user 鎖定。unlock(num, user):若節點 num 被 user 鎖定,則解鎖。upgrade(num, user):若節點 num 未被鎖定、至少有一個子孫被鎖定、且所有祖先都未被鎖定,則鎖定此節點並解鎖所有子孫。解題思路:
children)以支持向下搜尋。lock / unlock:直接檢查與更新鎖定狀態陣列。upgrade:
true。時間複雜度:
lock / unlock:O(1)upgrade:O(n) — 最壞情況需要遍歷所有祖先 O(h) + 所有子孫 O(n)。空間複雜度:O(n) — 儲存子節點列表和鎖定狀態。
1. Constructor: a. Build children list from parent array b. Initialize lockedBy array with -1 (unlocked) 2. lock(num, user): a. If lockedBy[num] != -1: return false b. Set lockedBy[num] = user, return true 3. unlock(num, user): a. If lockedBy[num] != user: return false b. Set lockedBy[num] = -1, return true 4. upgrade(num, user): a. If lockedBy[num] != -1: return false b. Walk up ancestors; if any locked: return false c. DFS descendants: unlock all locked ones, track if any found d. If no locked descendant found: return false e. Set lockedBy[num] = user, return true
BFS 取代 DFS:在搜尋子孫時使用 BFS(佇列),邏輯相同但對寬樹更易理解。時間複雜度不變。
懶更新 + 標記傳播:類似線段樹的懶標記,在需要時才傳播解鎖操作。可以攤銷 upgrade 的成本,但實作複雜度顯著增加,且本題約束下不必要。
upgrade 操作使其平均時間更短?(提示:維護鎖定子孫的計數)