題目詳見:LettCode 285. Inorder Successor in BST
解法一
思路
由於從根節點開始,我們可以利用中序遍歷的迭代寫法,並加入一個 prev 節點記錄上一次訪問的節點。當上一次訪問的節點值和目標節點值相同時,當前遍歷的節點就是我們要找的後繼。
程式碼
class Soution {
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
if (root == null) return null;
Stack<TreeNode> stack = new Stack<>();
TreeNode curr = root;
TreeNode prev = null;
while (!stack.isEmpty() || curr != null) {
while (curr != null) {
stack.push(curr);
curr = curr.left;
}
curr = stack.pop();
if (prev != null && prev.val == p.val) {
return curr;
}
prev = curr;
curr = curr.right;
}
return null;
}
}
複雜度分析
- 時間複雜度
- O(H) 遍歷整個樹
- 空間複雜度
- O(H) to keep the stack
題目詳見:510. Inorder Successor in BST II
解法一
思路
這道題沒有從根節點出發,而是需要直接找出一個節點的後繼。此時要分兩種情況討論。
因為中序遍歷的順序是 左 - 根 - 右,所以如果目標節點有右孩子,我們先將指標移動到右孩子,隨後一直尋找該節點的左孩子,直到沒有左孩子為止。
如果目標節點沒有右孩子,那麼需要一直向上回溯,直到找到一個節點,是父節點的左孩子,那麼這個父節點就是後繼。
程式碼
/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node parent;
};
*/
class Solution {
public Node inorderSuccessor(Node node) {
if (node.right != null) {
node = node.right;
while (node.left != null) {
node = node.left;
}
return node;
}
while (node.parent != null && node == node.parent.right) {
node = node.parent;
}
return node.parent;
}
}
複雜度分析
- 時間複雜度 O(H)
- 空間複雜度 O(1)
TakeAway
- 第二題不知道這個節點在那個位置,所以需要針對 inorder traversal 的性質來解題。
本作品採用《CC 協議》,轉載必須註明作者和本文連結