LeetCode 285 & 510. 二叉樹中序後繼 I & II

Borris發表於2020-02-24

題目詳見: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 協議》,轉載必須註明作者和本文連結

相關文章