[LeetCode] 510. Inorder Successor in BST II 二叉搜索樹中的中序後繼節點之二

 

Given a binary search tree and a node in it, find the in-order successor of that node in the BST.html

The successor of a node p is the node with the smallest key greater than p.val.node

You will have direct access to the node but not to the root of the tree. Each node will have a reference to its parent node.git

 

Example 1:github

Input: 
root = {"$id":"1","left":{"$id":"2","left":null,"parent":{"$ref":"1"},"right":null,"val":1},"parent":null,"right":{"$id":"3","left":null,"parent":{"$ref":"1"},"right":null,"val":3},"val":2}
p = 1 Output: 2 Explanation: 1's in-order successor node is 2. Note that both p and the return value is of Node type. 

Example 2:post

Input: 
root = {"$id":"1","left":{"$id":"2","left":{"$id":"3","left":{"$id":"4","left":null,"parent":{"$ref":"3"},"right":null,"val":1},"parent":{"$ref":"2"},"right":null,"val":2},"parent":{"$ref":"1"},"right":{"$id":"5","left":null,"parent":{"$ref":"2"},"right":null,"val":4},"val":3},"parent":null,"right":{"$id":"6","left":null,"parent":{"$ref":"1"},"right":null,"val":6},"val":5}
p = 6 Output: null Explanation: There is no in-order successor of the current node, so the answer is . null

Example 3:url

Input: 
root = {"$id":"1","left":{"$id":"2","left":{"$id":"3","left":{"$id":"4","left":null,"parent":{"$ref":"3"},"right":null,"val":2},"parent":{"$ref":"2"},"right":{"$id":"5","left":null,"parent":{"$ref":"3"},"right":null,"val":4},"val":3},"parent":{"$ref":"1"},"right":{"$id":"6","left":null,"parent":{"$ref":"2"},"right":{"$id":"7","left":{"$id":"8","left":null,"parent":{"$ref":"7"},"right":null,"val":9},"parent":{"$ref":"6"},"right":null,"val":13},"val":7},"val":6},"parent":null,"right":{"$id":"9","left":{"$id":"10","left":null,"parent":{"$ref":"9"},"right":null,"val":17},"parent":{"$ref":"1"},"right":{"$id":"11","left":null,"parent":{"$ref":"9"},"right":null,"val":20},"val":18},"val":15}
p = 15 Output: 17 

Example 4:spa

Input: 
root = {"$id":"1","left":{"$id":"2","left":{"$id":"3","left":{"$id":"4","left":null,"parent":{"$ref":"3"},"right":null,"val":2},"parent":{"$ref":"2"},"right":{"$id":"5","left":null,"parent":{"$ref":"3"},"right":null,"val":4},"val":3},"parent":{"$ref":"1"},"right":{"$id":"6","left":null,"parent":{"$ref":"2"},"right":{"$id":"7","left":{"$id":"8","left":null,"parent":{"$ref":"7"},"right":null,"val":9},"parent":{"$ref":"6"},"right":null,"val":13},"val":7},"val":6},"parent":null,"right":{"$id":"9","left":{"$id":"10","left":null,"parent":{"$ref":"9"},"right":null,"val":17},"parent":{"$ref":"1"},"right":{"$id":"11","left":null,"parent":{"$ref":"9"},"right":null,"val":20},"val":18},"val":15}
p = 13 Output: 15 

 

Note:code

  1. If the given node has no in-order successor in the tree, return null.
  2. It's guaranteed that the values of the tree are unique.
  3. Remember that we are using the Node type instead of TreeNode type so their string representation are different.

 

Follow up:htm

Could you solve it without looking up any of the node's values?blog

 

這道題是以前的那道 Inorder Successor in BST 的後續,以前那道題給了咱們樹的根結點,而這道題並無肯定給咱們根結點,只是給了樹的任意一個結點,而後讓求給定結點的中序後繼結點。這道題比較好的一點就是例子給的比較詳盡,基本覆蓋到了大部分的狀況,包括一些很 tricky 的狀況。首先來看例子1,結點1的中序後繼結點是2,由於中序遍歷的順序是左-根-右。仍是例子1,結點2的中序後續結點是3,這樣咱們就知道中序後續結點能夠是其父結點或者右子結點。再看例子2,結點6的中序後續結點是空,由於其已是中序遍歷的最後一個結點了,因此沒有後續結點。例子3比較 tricky,結點 15 的中序後續結點不是其右子結點,而是其右子結點的左子結點 17,這樣才符合左-根-右的順序。例子4一樣 tricky,結點 13 的中序後繼結點並非其親生父結點,而是其祖爺爺結點 15。

好,看完了這四個例子,咱們應該內心有些數了吧。後繼結點出現的位置大體能夠分爲兩類,一類是在子孫結點中,另外一類是在祖先結點中。仔細觀察例子不難發現,當某個結點存在右子結點時,其中序後繼結點就在子孫結點中,反之則在祖先結點中。這樣咱們就能夠分別來處理,當右子結點存在時,咱們須要找到右子結點的最左子結點,這個不難,就用個 while 循環就好了。當右子結點不存在,咱們就要找到第一個比其值大的祖先結點,也是用個 while 循環去找便可,參見代碼以下:

 

解法一:

class Solution {
public:
    Node* inorderSuccessor(Node* node) {
        if (!node) return nullptr;
        Node *res = nullptr;
        if (node->right) {
            res = node->right;
            while (res && res->left) res = res->left;
        } else {
            res = node->parent;
            while (res && res->val < node->val) res = res->parent;
        }
        return res;
    }
};

 

本題的 Follow up 讓咱們不要訪問結點值,那麼上面的解法就不行了。由於當 node 沒有右子結點時,咱們無法經過比較結點值來找到第一個大於 node 的祖先結點。雖然不能比較結點值了,咱們仍是能夠經過 node 相對於其 parent 的位置來判斷,當 node 是其 parent 的左子結點時,咱們知道此時 parent 的結點值必定大於 node,由於這是二叉搜索樹的性質。若 node 是其 parent 的右子結點時,則將 node 賦值爲其 parent,繼續向上找,直到其 parent 結點不存在了,此時說明不存在大於 node 值的祖先結點,這說明 node 是 BST 的最後一個結點了,沒有後繼結點,直接返回 nullptr 便可,參見代碼以下:

 

解法二:

class Solution {
public:
    Node* inorderSuccessor(Node* node) {
        if (!node) return nullptr;
        if (node->right) {
            node = node->right;
            while (node && node->left) node = node->left;
            return node;
        }
        while (node) {
            if (!node->parent) return nullptr;
            if (node == node->parent->left) return node->parent;
            node = node->parent;
        }
        return node;
    }
};

 

Github 同步地址:

https://github.com/grandyang/leetcode/issues/510

 

相似題目:

Inorder Successor in BST

 

參考資料:

https://leetcode.com/problems/inorder-successor-in-bst-ii/

https://leetcode.com/problems/inorder-successor-in-bst-ii/discuss/231587/Java-find-in-parents-or-find-in-descendents

https://leetcode.com/problems/inorder-successor-in-bst-ii/discuss/234295/Java-easy-understanding-well-explained-solution

 

LeetCode All in One 題目講解彙總(持續更新中...)

相關文章
相關標籤/搜索