二叉樹最近公共祖先節點


尋找最近公共祖先節點(LCA) 
        

在一棵二叉樹中,對於節點X和節點Y,X和Y的LCA是這棵樹中X和Y的第一個共同祖先。尋找公共節點的算法思路很簡單:對於節點x和y,找到樹的根節點分別到x節點和y節點的路徑(並不是遍歷),並分別記錄在兩個數組中(或其他),數組中索引為0的元素為樹的根節點,索引越小的元素離待x和y節點越遠。且兩個數組前面肯定有對應相同的元素。此時問題變為正向查找兩個數組中第一個不相同元素的前一個(相同),即最后一個相同的元素。

1.如果這棵二叉樹是二叉查找樹,那么記錄根節點到x和y節點的路徑問題變得很簡單,借助於二叉查找樹的性質,借助BST的查找過程,很簡單便可以做到。例:leetcode_235 LowestCommon Ancestor of a Binary Search Tree:Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.

代碼:

/**
 * 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:
void find1(TreeNode* root,TreeNode* p,vector<TreeNode*> &v)
{
     if(root == p)
     {
         v.push_back(root); 
         return ;
     }
     if(p->val > root->val)
     {
         v.push_back(root);
         find1(root->right,p,v); 
     } 
     else
     {
         v.push_back(root);
         find1(root->left,p,v); 
     }
}
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
         if(root == NULL || p == NULL || q == NULL)
     return NULL;
     vector<TreeNode*> v1;
     vector<TreeNode*> v2;
     find1(root,p,v1);     
     find1(root,q,v2);
     int i,j;
     //cout<<v1.size()<<endl;
     //cout<<v2.size()<<endl;
     
     for(i = 0,j = 0;i<v1.size()-1,j<v2.size()-1;i++,j++)
     {
         if(v1[i] == v2[j] && v1[i+1] != v2[j+1]) 
         break;
     }
     return v1[i];
    }
};

2.若一棵樹是普通的二叉樹,則二叉排序樹在查找方面的特性不能應用。在普通二叉樹中,尋找從根節點到任意節點的路徑不像是在BST中那么簡單,我們先要解決這個問題。例:leetcode-236 Lowest Common Ancestor of a Binary Tree 

bool findP(TreeNode *root,TreeNode *p,vector<TreeNode*> &v)//遞歸查找,路徑記錄在v中
{
     if(p==NULL || root == NULL)
     return false;
     v.push_back(root);
     if(root == p)
     return true;
     if(root->left != NULL && findP(root->left,p,v) == true )
     {
         return true;
     }
     if(root->right != NULL && findP(root->right,p,v) == true)
     {
        return true;
     }
     v.pop_back();//在該子樹上查找失敗,則刪除這個根節點
     return false;
}

接下來的思路和上述一樣,正向查找兩個數組中第一個不相同元素的前一個(相同),即最后一個相同的元素。

TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
{
      if(root == NULL || p == NULL || q == NULL)
      {
              return NULL;
      }
      vector<TreeNode *> v1;
      findP(root,p,v1);
      vector<TreeNode*> v2;
      findP(root,q,v2);
      int len = v1.size()<v2.size()?v1.size():v2.size();
      int i = 0;
      for(i = 0;i<len-1;i++)
      {
          if(v1[i] == v2[i] && v1[i+1]!=v2[i+1])
          break;
      }
      return v1[i];
}



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM