代码随想录——26、二叉(搜索)树的最近公共祖先
1.代码随想录-逆波兰式、滑动窗口最大值2.代码随想录-栈与队列-有效的括号(括号匹配)3.代码随想录——栈与队列8-前K个高频元素4.二叉树的递归遍历和迭代遍历5.代码随想录——二叉树-11.完全二叉树的节点个数6.代码随想录——二叉树-12.平衡二叉树7.代码随想录——二叉树17-路径总和8.代码随想录——二叉树19.最大二叉树9.代码随想录——二叉树21、合并二叉树(附:递归算法复杂度分析)10.代码随想录——二叉树23、验证二叉搜索树11.代码随想录——25二叉搜索树的最小绝对值差(递归遍历如何记录前后两个指针)12.代码随想录——25.二叉搜索树中的众数
13.代码随想录——26、二叉(搜索)树的最近公共祖先
14.代码随想录——回溯8、组合总和II15.代码随想录——回溯9.分割回文串16.代码随想录——回溯19重新安排行程17.代码随想录——回溯 N皇后18.代码随想录——贪心8.跳跃游戏II19.代码随想录——贪心9.K次取反后最大化的数组和 && std::sort函数的第三个参数说明20.代码随想录——贪心13.分发糖果21.代码随想录——贪心算法:根据身高重建队列 & Vector原理22.代码随想录——贪心算法22单调递增的数字23.代码随想录——贪心23监控二叉树24.代码随想录——动态规划5.周总结25.代码随想录——动态规划9不同的二叉搜索树26.代码随想录——动态规划01背包27.代码随想录——动态规划13.分割等和子集28.代码随想录——动态规划14最后一块石头的重量II(01背包)29.动态规划——dp的含义归类(完全背包和01背包区别)30.动态规划——26单词拆分31.代码随想录——动态规划背包问题总结32.代码随想录——动态规划31打家劫舍III(树状DP)33.代码随想录——动态规划、股票问题34.代码随想录——单调栈35.回溯总结
递归
最近公共祖先定义:设节点 root 为节点 p,q 的某公共祖先,若其左子节点 root.left 和右子节点root.right 都不是 p,q 的公共祖先,则称 root 是“最近的公共祖先”。
若 root是 p,q的 最近公共祖先 ,则只可能为以下情况之一
- 如果p和q在节点root的两侧,那么root就是最近公共祖先
- p = root ,且 q 在 root 的左或右子树中
- q = root ,且 p 在 root 的左或右子树中
具体解法
- 回溯:如果遇到p,q就返回p,q;如果是空节点返回null;如果左右子树不为空则返回当前节点
二叉树只能通过后序遍历(即:回溯)实现从底向上的遍历方式。
- 要理解如果返回值left为空,right不为空为什么要返回right,为什么可以用返回right传给上一层结果
代码
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == nullptr)return nullptr;
if(p == root || q == root)return root;
TreeNode* left = lowestCommonAncestor(root->left,p,q);
TreeNode* right = lowestCommonAncestor(root->right,p,q);
if(left != nullptr && right != nullptr)return root;
if(left != nullptr)return left;
if(right != nullptr)return right;
return nullptr;
}
};
二叉搜索树
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
// 利用二叉搜索树特性:公共祖先的val一定在p和q的val之间,从上至下递归/搜索找到的第一个满足[p->val,q->val]的就是最近公共祖先
// 1. 递归法
if(root == nullptr)return nullptr;
if(root->val < p->val && root->val < q->val){//小于p和q——cur,p,q / cur,q,p 则访问右子树
return lowestCommonAncestor(root->right,p,q);
}if(root->val > p->val && root->val > q->val){
return lowestCommonAncestor(root->left,p,q);
}
return root;//在[p->val,q->val]左闭右闭区间,直接返回
//2. 迭代法
//利用二叉搜索树自带方向性
while(root){
if(root->val < p->val && root->val < q->val){//小于p和q——cur,p,q / cur,q,p 则访问右子树
root = root->right;
}else if(root->val > p->val && root->val > q->val){
root = root->left;
}else return root;
}
return NULL;
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)