【LeetCode】【树】剑指 Offer 68 - I,II. 二叉树的最近公共祖先 思路解析和代码

剑指 Offer 68 - I,II

题目链接

个人思路

思路

该题要求解最近公共祖先,关键是需要知道给出的两个结点p,q是在左子树还是在右子树,即关键是要知道p,q的准确位置,而不是结点出现的顺序
理一下最初的错误思路,最初是想着如何划分左右子树来找p,q的位置

  • 只想到了当一个位于左子树一个位于右子树,则他们的公共祖先是根节点;
  • 但两节点存在父子关系,这样的情况还不知道如何处理;
  • 还想到了遍历树,因为祖先是存在先后关系的,通过遍历的方法找到最近公共祖先,遍历只能找出祖先出现的顺序,而不能准确得知结点的位置
基础-二叉搜索树

利用二叉搜索树的性质来确定p,q两结点的位置

  • 如果当前节点值大于p,q两个节点,说明p,q均在左子树
  • 如果当前节点值小于p,q两个节点,说明p,q均在右子树
  • 首先找到p,q之间的节点,即为最近公共祖先

一开始看了解析,却还是没有想到如何利用二叉搜索树的性质,还是想采用层序遍历的方法

进阶-普通二叉树

利用递归,搜索左右子树,直到找到p,q来确定两结点的位置

  • 递归出口:当前节点为空返回null
  • 递归体:递归遍历左子树和右子树,寻找p,q,若当前节点与其中一个相等,说明找到了便返回当前节点;若左子树返回值为null,说明p,q在右子树中,若右子树返回值为null,说明p,q在左子树中,若二者均不为空,说明p,q位于左右两侧,则返回当前节点

个人思路代码

剑指 Offer 68 - I
/**
 * 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* ans;
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root == NULL){
            return NULL;
        }
        if(root->val > p->val && root->val > q->val){//当前值大于两个节点的值,说明公共祖先在左子树
            return lowestCommonAncestor(root->left, p, q);//返回左子节点
        }
        else if(root->val < p->val && root->val < q->val){//当前值小于两个节点的值,说明公共祖先在右子树
            return lowestCommonAncestor(root->right, p, q);//返回右子节点
        }
        else{
            return root;//返回当前节点
        }
        return root;
    }
};
剑指 Offer 68 - II
/**
 * 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 == NULL){
            return NULL;
        }
        if(root == p || root == q){//在左右子树中寻找p,q,找到则说明公共祖先即为root(一个节点也可以是它自己的祖先)
            return root;
        }
        TreeNode* tleft = lowestCommonAncestor(root->left, p, q);//递归遍历左子树,只要在左子树中找到了p或q,则先找到谁就返回谁
        TreeNode* tright = lowestCommonAncestor(root->right, p, q);//递归遍历右子树,只要在右子树中找到了p或q,则先找到谁就返回谁
        if(tleft == NULL){//在左子树中没有找到p或q,说明pq在右子树中
            return tright;
        }
        else if(tright == NULL){//在右子树中没有找到p或q,说明pq在左子树中
            return tleft;
        }
        else{//到此处,说明左右子树均不为空,应返回根节点
            return root;
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值