0235-二叉搜尋樹的最近公共祖先

weixin_34320159發表於2019-01-24

二叉搜尋樹的最近公共祖先

方案一


由於二叉搜尋樹的特點是左<根<右,所以根節點的值一直都是中間值,大於左子樹的所有節點值,小於右子樹的所有節點值,那麼我們可以做如下的判斷,如果根節點的值大於p和q之間的較大值,說明p和q都在左子樹中,那麼此時我們就進入根節點的左子節點繼續遞迴,如果根節點小於p和q之間的較小值,說明p和q都在右子樹中,那麼此時我們就進入根節點的右子節點繼續遞迴,如果都不是,則說明當前根節點就是最小共同父節點,直接返回即可

C++-原始碼


#include <iostream>
//#include <queue>
//#include <unordered_map>

using namespace std;

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        
        if (!root) {
            
            return root;
        }
        
        if (root->val > max(p->val, q->val)) {
            
            return lowestCommonAncestor(root->left, p, q);
        }
        else if (root->val < min(p->val, q->val)) {
            
            return lowestCommonAncestor(root->right, p, q);
        }
        else {
            
            return root;
        }
    }
};

方案二


如果當前結點不為空,且既不是p也不是q,那麼根據上面的分析,p和q的位置就有三種情況,p和q要麼分別位於左右子樹中,要麼同時位於左子樹,或者同時位於右子樹。我們需要優化的情況就是當p和q同時為於左子樹或右子樹中,而且返回的結點並不是p或q,那麼就是p和q的最小父結點了,已經求出來了,就不用再對右結點呼叫遞迴函式了

C++-原始碼


class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        
        while (true) {
            
            if (root->val > max(p->val, q->val)) {
                
                root = root->left;
            }
            else if (root->val < min(p->val, q->val)) {
                
                root = root->right;
            }
            else {
                
                return root;
            }
        }
    }
};

參考Grandyang

相關文章