zoukankan      html  css  js  c++  java
  • 二叉树最近公共祖先节点

    寻找最近公共祖先节点(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];
    }


  • 相关阅读:
    gulp编译sass
    Material Design学习
    js爬虫心得
    js爬虫
    angularjs
    sass心得
    矩阵与线性代数学习笔记
    2-SAT学习笔记
    一个有趣的题目【二分答案,2-SAT,线段树优化】
    vijos训练之——星辰大海中闪烁的趣题
  • 原文地址:https://www.cnblogs.com/sunp823/p/5601418.html
Copyright © 2011-2022 走看看