タイトルリンク: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を最大値、次に:
- rootの値がvallowの値以上で、valhighの値以下の場合、それは2つの値の間にあり、2つのノードがその左右のサブツリーにあることを意味します。ルートは最も近い共通の祖先です。
- それ以外の場合、rootの値がvalhighの値よりも大きい場合は、2つのノードの値が両方ともrootの値よりも小さいことを意味します。つまり、両方が左側のサブツリーにあり、左側に入力します。検索するルートのサブツリー。
- それ以外の場合、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;
}
};