【LeetCode剑指offer】二叉搜索树的最近公共祖先(迭代or递归)

简介: 求两个节点的最近公共祖先的题目我们做过,但是这题是二叉搜索树BST,并且本题中所有节点的数值都是不同的,所以可以根据BST的数值特点进行判断,即左子树的所有节点都比当前节点小,右子树的所有节点都比当前节点数值大。

一、题目

image.pngimage.png



二、思路

求两个节点的最近公共祖先的题目我们做过,但是这题是二叉搜索树BST,并且本题中所有节点的数值都是不同的,所以可以根据BST的数值特点进行判断,即左子树的所有节点都比当前节点小,右子树的所有节点都比当前节点数值大。


若 root 是 p,q 的 最近公共祖先 ,则只可能为以下情况之一:


p 和 q 在 root 的子树中,且分列 root 的 异侧(即分别在左、右子树中);

p = root,且 q 在 root 的左或右子树中;

q = root,且 p 在 root 的左或右子树中;

image.png


方法一:迭代法

循环搜索: 当节点 root 为空时跳出;

当 p, q 都在 root 的 右子树 中,则遍历至 root.right ;

否则,当 p, q 都在 root 的 左子树 中,则遍历至 root.left ;

否则,说明找到了 最近公共祖先 ,跳出。

返回值: 最近公共祖先 root 。

/**
 * 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) {
        while(root){
            if(root->val < p->val && root->val < q->val){
                root = root->right;
            }else if(root->val > p->val && root->val > q->val){
                root = root->left;
            }else{
                break;
            }
        }
        return root;
    }
};

时间复杂度:O(N),其中N为二叉树节点数,每while训练一轮就“处理”完一层,BST树的最小高度为logN,最大高度为N(退化为链表)。

空间复杂度:O(1),使用常数大小的额外空间。

image.png


方法二:递归

其实就是把迭代法中的while循环去掉,还是分三种情况,但是在前两种情况里递归。

/**
 * 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(p->val > root->val && q->val > root->val){
            return lowestCommonAncestor(root->right, p, q);
        }else if(p->val < root->val && q->val < root->val){
            return lowestCommonAncestor(root->left, p, q);
        }
        return root;
    }
};
相关文章
|
7月前
|
Go 开发者 索引
【LeetCode 热题100】路径与祖先:二叉树中的深度追踪技巧(力扣33 / 81/ 153/154)(Go语言版)
本文深入探讨了LeetCode中四道关于「搜索旋转排序数组」的经典题目,涵盖了无重复和有重复元素的情况。通过二分查找的变形应用,文章详细解析了每道题的解题思路和Go语言实现代码。关键点包括判断有序区间、处理重复元素以及如何缩小搜索范围。文章还总结了各题的异同,并推荐了类似题目,帮助读者全面掌握二分查找在旋转数组中的应用。无论是初学者还是有经验的开发者,都能从中获得实用的解题技巧和代码实现方法。
312 14
|
8月前
|
Go
【LeetCode 热题100】路径与祖先:二叉树中的深度追踪技巧(力扣437 / 236 )(Go语言版)
本文深入探讨二叉树中路径与祖先问题,涵盖两道经典题目:LeetCode 437(路径总和 III)和236(最近公共祖先)。对于路径总和 III,文章分析了双递归暴力解法与前缀和优化方法,后者通过哈希表记录路径和,将时间复杂度从O(n²)降至O(n)。在最近公共祖先问题中,采用后序遍历递归查找,利用“自底向上”的思路确定最近公共祖先节点。文中详细解析代码实现与核心要点,帮助读者掌握深度追踪技巧,理解树结构中路径与节点关系的本质。这类问题在面试中高频出现,掌握其解法意义重大。
187 4
【LeetCode 45】701.二叉搜索树中的插入操作
【LeetCode 45】701.二叉搜索树中的插入操作
99 1
【LeetCode 44】235.二叉搜索树的最近公共祖先
【LeetCode 44】235.二叉搜索树的最近公共祖先
104 1
【LeetCode 48】108.将有序数组转换为二叉搜索树
【LeetCode 48】108.将有序数组转换为二叉搜索树
127 0
【LeetCode 47】669.修剪二叉搜索树
【LeetCode 47】669.修剪二叉搜索树
80 0
【LeetCode 46】450.删除二叉搜索树的节点
【LeetCode 46】450.删除二叉搜索树的节点
159 0
【LeetCode 43】236.二叉树的最近公共祖先
【LeetCode 43】236.二叉树的最近公共祖先
129 0
【LeetCode 42】501.二叉搜索树中的众数
【LeetCode 42】501.二叉搜索树中的众数
107 0
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
254 6
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行

热门文章

最新文章