1. 程式人生 > >LCA最小公共父節點的解題思路

LCA最小公共父節點的解題思路

都在 com 就是 位置 如果 前序遍歷 int min html

LCA最小公共父節點解法:

1、二叉搜索樹:

中序遍歷是升序,前序遍歷即按序插入建樹的序列。

二叉搜索樹建樹最好用前序+中序,如果用前序建樹,最壞情況會退化為線性表,超時。

最近公共祖先甲級: A1143,1151

利用二叉搜索樹的性質尋找結點u和v的最低公共祖先(遞歸解法)
1)如果根結點的值大於max(u,v),說明u和v均在根結點的左子樹,則進入根結點的左子結點繼續遞歸
2)如果根結點的值小於min(u,v),說明u和v均在根結點的右子樹,則進入根結點的右子結點繼續遞歸
3)剩下的情況就是,根結點的值比其中一個值大,比另外一個小,則該結點就是結點u,v的最低公共祖先了

二叉搜索樹核心代碼:

Node* getLCA(Node* root,int u,int v)
{
    if(root==nullptr) return nullptr;
    if(root->val > max(u,v)) return getLCA(root->lchild,u,v);
    else if(root->val < min(u,v)) return getLCA(root->rchild,u,v);
    else return root;
}

2、普通二叉樹

遞歸解法
在遞歸函數中,我們首先判斷當前結點是否為空,若為空,直接返回;或者,當前結點是否就是u或v,若是,也直接返回該結點。否則,就對其左右孩子結點分別調用遞歸函數。可以想到,結點u和v有以下三種情況:
  1)u和v分別位於當前結點的左右兩側;
  2)u和v都在當前結點的左子樹中;
  3)u和v都在當前結點的右子樹中。
若u和v分別位於左右子樹中,那麽對左右子結點調用遞歸函數,會分別返回u和v結點的位置,而當前結點正好就是u和v的最小共同父結點,直接返回當前結點即可。

若u和v同時位於左子樹,這裏有兩種情況,一種情況是left會返回u和v中較高的那個位置,而right會返回空,所以我們最終返回非空的left即可;還有一種情況是會返回u和v的最小父結點,就是說當前結點的左子樹中的某個結點才是u和v的最小父結點,會被返回。

若u和v同時位於右子樹,同樣這裏有兩種情況,一種情況是right會返回u和v中較高的那個位置,而left會返回空,所以我們最終返回非空的right即可,還有一種情況是會返回u和v的最小父結點,就是說當前結點的右子樹中的某個結點才是u和v的最小父結點,會被返回。

核心代碼:

Node* getLCA(Node* root,int u,int v)
{
    if(root==nullptr || root->val==u || root->val==v) return root;
    Node* left=getLCA(root->lchild,u,v);
    Node* right=getLCA(root->rchild,u,v);
    if(left && right) return root;
    else return (left?left:right);
}

參考:https://www.cnblogs.com/kkmjy/p/9529771.html

LCA最小公共父節點的解題思路