中序&&递归&&剑指 Offer 68 - II. 二叉树的最近公共祖先

博客作者探讨了两种求解二叉搜索树中两个节点最近公共祖先的方法:中序遍历+循环判断以及递归解法。第一种方法虽然正确,但存在冗余操作,增加了时间复杂度。第二种递归解法更为优化,减少了不必要的判断。博主分享了这两种方法的实现代码,并提到了通过递归解法可以显著提升效率。
摘要由CSDN通过智能技术生成

1.中序遍历+循环判断(结合二叉搜索树那题,自己写的代码

昨天的二叉搜索树:
递归&&迭代&&剑指 Offer 68 - I. 二叉搜索树的最近公共祖先

依旧按照三种情况判断两个结点在左孩子、右孩子、异侧的情况,不过判断操作单独写在一个void dfs()函数里面。解答过程中,画图分析代码错误最后写出来,这个有冗余操作,每一次都要判断两个结点在哪一边(调用dfs()函数),增加了时间复杂度。

/**
 * 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:
    int pnum,qnum,count;
    void dfs(TreeNode*root,int rnum){	//判断p,q位于左孩子、右孩子、异侧
        if(!root)   return ;
        dfs(root->left,rnum);
        if(root->val==rnum)   return;	//剪枝操作,只需要判断左边有无p,q,中序遍历
        if(root->val==pnum||root->val==qnum)    count+=1;
        dfs(root->right,rnum);
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        pnum=p->val;
        qnum=q->val;
        while(root){
            count=0;
            dfs(root,root->val);
           // cout<<root->val<<" "<<"count="<<count<<endl;
            if(root!=p&&root!=q){
                if(count==2)    root=root->left;
                else if(count==0)  root=root->right;
                else    break;
            }
            else break;
        }
        return root;
    }
};

2.递归(参考大佬的解法,极大优化时间复杂度,减少冗余操作

附上大佬力扣题解:
剑指 Offer 68 - II. 二叉树的最近公共祖先(DFS ,清晰图解)

递归:(1)终止条件;(2)递归工作;(3)返回值。

这里返回值有四种情况,原来直接返回结点就好了。

/**
 * 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||root==p||root==q){
            return root;
        }
        TreeNode*left=lowestCommonAncestor(root->left,p,q);
        TreeNode*right=lowestCommonAncestor(root->right,p,q);
        if(left==NULL){
            return right;
        }
        if(right==NULL){
            return left;
        }
        return root;
    }
};

刷完剑指offer的简单题了。

发完昨晚那篇blog,积分达到400,博客等级升到3,换了个皮肤,增加了"K神"的标签(狗头

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值