Likou235二分探索木の最も近い共通の祖先

タイトルリンク:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree

二分探索木が与えられた場合、ツリー内の2つの指定されたノードの最も近い共通の祖先を見つけます。

Baidu Encyclopediaでの最も近い共通祖先の定義は次のとおりです。「ルートツリーTの2つのノードpとqの場合、最も近い共通祖先はノードxとして表され、xがpとqの祖先であり、深さを満たします。 xのは可能な限り大きくなります(ノードはそれ自体の祖先になることもできます)。」

たとえば、次の二分探索木があるとします。root= [6,2,8,0,4,7,9、null、null、3,5]

 

例1:

入力:ルート= [6,2,8,0,4,7,9、null、null、3,5]、p = 2、q = 8
出力:6 
説明:ノード2とノード8の最も近い共通の祖先6です。
例2:

入力:ルート= [6,2,8,0,4,7,9、null、null、3,5]、p = 2、q = 4
出力:2
説明:ノード2とノード4の最も近い共通の祖先定義によれば、最も近い共通の祖先ノードはノード自体である可能性があるため、は2です。
 

説明:

  • すべてのノードの値は一意です。
  • pとqは異なるノードであり、両方とも指定された二分探索木に存在します。

 

        実際には非常に単純です。要求は値ではなくノードを返すことであることに注意してください。二分探索木であるため、ノードの左側のサブツリー内のすべてのノードの値はこのポイントの値以下であり、左側のサブツリー内のすべてのノードの値はまたはこの点の値に等しい、元のタイトルの説明の記事「すべてのノードの値は一意である」の最初の場合、上記の状況に等しいものはありません。つまり、ルートノードの場合、いずれかのノードの値がその値よりも小さい場合、そのノードは左側のサブツリーに配置され、より大きい場合は右側のサブツリーに配置されます。2つのノードがルートノードの左右のサブツリーにある場合(つまり、ルートノードの値が2つのノードの値の間にある場合)、それらの最も近い共通の祖先がルートノードであることは明らかです。それ以外の場合、2つのノードは同時にルートノードの左右のサブツリーに配置されます(つまり、両方のノードがルートノードの値よりも大きいか小さい)、2つのノードの最も近い共通の祖先は次のようになります。また、左右のサブツリーにあり、最も近い共通の祖先の値が2つのノードの値の間に導入されます。

        アルゴリズムは再帰/反復によって完了することができます。入力はサブツリーのルートノードであり、2つのノードpとqです。vallowをpとqの2つのノード値の最小値とし、valhighを最大値、次に:

  1. rootの値がvallowの値以上で、valhighの値以下の場合、それは2つの値の間にあり、2つのノードがその左右のサブツリーにあることを意味します。ルートは最も近い共通の祖先です。
  2. それ以外の場合、rootの値がvalhighの値よりも大きい場合は、2つのノードの値が両方ともrootの値よりも小さいことを意味します。つまり、両方が左側のサブツリーにあり、左側に入力します。検索するルートのサブツリー。
  3. それ以外の場合、rootの値はvallowの値よりも小さく、2つのノードの値がrootの値よりも大きいことを示します。つまり、両方が右側のサブツリーにあり、の右側のサブツリーに入ります。検索するルート。

       ケース1の両側で等号が使用される理由は、最も近い共通の祖先ノードがノード自体である可能性があるためです。したがって、等しい状況が発生した場合、2つのノードの1つがルートノードであることを意味します。

再帰的方法:

/**
 * Definition for a binary tree node.
 * 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) {
        int vallow=min(p->val,q->val);
        int valhigh=max(p->val,q->val);
        if (vallow<=root->val && valhigh>=root->val)
            return root;
        else if(valhigh<root->val)
            return lowestCommonAncestor(root->left,p,q);
        else
            return lowestCommonAncestor(root->right,p,q);
        }
};

反復法:

/**
 * Definition for a binary tree node.
 * 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) {
        TreeNode* r=root;
        int vallow=min(p->val,q->val);
        int valhigh=max(p->val,q->val);
        while(r){
            if (vallow<=r->val && valhigh>=r->val)
                break;//其实这行可以直接return r的,但是不通过
            else if(valhigh<r->val)
                r=r->left;
            else
                r=r->right;
        }
        return r;
    }
};

 

おすすめ

転載: blog.csdn.net/qq_36614557/article/details/108835718