1. 程式人生 > >經典面試題——求任意兩個葉節點中最近的父節點

經典面試題——求任意兩個葉節點中最近的父節點

以下程式未經測試,僅供參考!

#include <iostream>
#include <vector>
using namespace std;


struct LCATreeNode{
  LCATreeNode* m_pLeft;
  LCATreeNode* m_pRight;
  int m_value;
}


bool nodePath(LCATreeNode* root, int value, vector<LCATreeNode*>& v){
  if(!root) return false;
  if(root->m_value != value){
    if(nodePath(root->m_pLeft,value,v)||nodePath(root->m_pRight,value,v)){
      v.push_back(root);
      return true;
    }else
      return false;
  }else{
    v.push_back(root);
    return true;
  }
}


LCATreeNode* findLCA(LCATreeNode* root, int value1,int value2){
  if(!root) return null;
  vector<LCATreeNode*> v1;
  vector<LCATreeNode*> v2;
  bool find = nodePath(root,value1,v1);
  find &= nodePath(root,value2,v2);
  if(find){
    int min = v1.size()<v2.size()?v1.size():v2.size();
    for(int i = v1.size()-min, j = v2.size()-min; i < v1.size(); i++,j++){
      if(v1[i]==v2[j])
        return v1[i];
    }
  }
  return null;
}

該程式的思路就是,首先求出兩個葉節點的路徑,將其分別儲存在兩個向量中,從同一層開始判斷是否有公共子節點。其實這個已經和兩個連結串列中第一個公共節點的題目很相似了!反正思路是一樣的。

該問題有以下幾個變體:

1)求任意兩個葉節點最長的距離。只要對公共部分進行計數a,兩個葉節點的距離分別是l1,l2則最長距離為 l1+l2-2*a

2)求二叉搜尋樹的任意兩個節點的公共父節點。這裡要注意利用二叉搜尋樹的特性,即任意兩個葉節點的父節點的值一定是在這兩個葉節點值得中間,因此程式碼如下所示,同樣未經驗證,僅供參考!

LCATreeNode* findLCA_1(LCATreeNode* root, int value1, int value2){
  LCATreeNode* tmp = root;
  while(tmp){
    if(tmp->m_value>value1 && tmp->m_value>value2)
      tmp = tmp->m_pLeft;
    else if(tmp->m_value<value1 && tmp->m_value<value2)
      tmp = tmp->m_pRight;
    else
      return tmp;
  }
  return null;
}