您的位置:首页 > 职场人生

面试题68 - I. 二叉搜索树的最近公共祖先

2020-04-03 07:27 691 查看

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树:  root = [6,2,8,0,4,7,9,null,null,3,5]

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6 
解释: 节点 2 和节点 8 的最近公共祖先是 6。

自己的思路:

1.由于属于二叉搜索树,左子节点小于父节点,右子节点大于父节点,这一点是否有用处呢?

分情况讨论:

①分别属于左右子树的节点,则公共节点为根节点;

②分别属于根节点的左子树的左节点,则找到比他们都大一点的最小父节点;

③分别属于根节点左子树的右节点,则找到比他们都小一点的最大父节点‘

④分别属于根节点左子树的左右节点,则找到他们的公共值节点;

⑤属于右子树的节点是否与上述情况对称?

2.剑指offer解答:

一、假如是二叉搜索树?

答:二又搜索树是排序过的, 位于左子树的节点都比父节点小,

而位于右子树的节点都比父节点大, 我们只需要从树的根节点开始和两个输入的节点进行比较。

如果当前节点的值比两个节点的值都大, 那么最低的共同父节点在当前节点的左子树中, 于是下一步遍历当前节点的左子节点。如果当前节点的值比两个节点的值都小,那么最低的共同父节定在当前节点的右子树中, 于是下步遍历当前节点的右子节点。

这样, 在树中从上到下找到的个在两个输入节点的值之间的节点就是最低的公共祖先。

二、加入不是二叉搜索树,甚至不是二叉树,只是普通的树呢?

答:树的节点中有没有指向父节点的指针?

如果有,可以转换成求两个链表的第一个公共节点。

 

yi的代码:(自己的有点问题)

/**

 * 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* leftNode=root->left;

        TreeNode* rightNode=root->right;

        while(root){

            if(p->val<root->val&&q->val>root->val)

            {

                return root;

            }

            else if(p->val>root->val&&q->val<root->val)

            {

                return root;

            }

            else if(p->val>root->val&&q->val>root->val)

            {

                root=root->right;

                return lowestCommonAncestor(root,p,q);

            }

            else(p->val<root->val&&q->val<root->val)

            {

                root=root->left;

                return lowestCommonAncestor(root,p,q);

            }

 

        }

        return root;

        */

//运用递归的思路解答问题:

        if((root -> val - p->val)*(root -> val - q ->val) <= 0 ){

            return root;

        }

        if(root -> val > p -> val){

            return lowestCommonAncestor(root -> left, p, q);

        }

        if(root -> val < p -> val){

            return lowestCommonAncestor(root -> right, p, q);

        }

        return NULL;

 

        

    }

};

面试题68 - II. 二叉树的最近公共祖先

难度简单30

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉树:  root = [3,5,1,6,2,0,8,null,null,7,4]

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和节点 1 的最近公共祖先是节点 3。

剑指offer思路:

所谓两个节点的公共祖先, 指的是这两个节点都出现在某个节点的子树。

从根节点开始遍历一棵树,每遍历一个节点时, 判断两个输入节点是不是在它的子树中。

如果在子树中,则分别遍历它的所有子节点并判断两个输入节点是不是在它们的子树,
这样从上到直找到的一个节点, 它自己的子树中同时包含两个输入的节点,

而它的子节点却没有, 那么该节点就是最低的公共祖先。

 

/**

 * 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) {

        //前序遍历???

        if(!root || root == p || root == q) return root;                //若当前为空或者匹配,则返回自身

        TreeNode* left = lowestCommonAncestor(root->left, p, q);          //左子树

        TreeNode* right = lowestCommonAncestor(root->right, p, q);      //右子树

        if(!left) return right;                                         

        if(!right) return left;

 

        return root;

 

        

    }

};

 

 

  • 点赞
  • 收藏
  • 分享
  • 文章举报
Daily96 发布了6 篇原创文章 · 获赞 0 · 访问量 52 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: