【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;
    }
};
相关文章
|
1月前
|
存储 算法 数据可视化
力扣156题最全解法:如何上下翻转二叉树(递归与迭代方法详解,附图解)
力扣156题最全解法:如何上下翻转二叉树(递归与迭代方法详解,附图解)
|
1月前
|
存储 算法 数据可视化
LeetCode 题目 96:从动态规划、递归到卡塔兰数实现不同的二叉搜索树
LeetCode 题目 96:从动态规划、递归到卡塔兰数实现不同的二叉搜索树
|
1月前
|
存储 算法 数据可视化
LeetCode 131题详解:高效分割回文串的递归与动态规划方法
LeetCode 131题详解:高效分割回文串的递归与动态规划方法
|
1月前
|
算法 数据可视化 数据挖掘
LeetCode题目104: 二叉树的最大深度(递归\迭代\层序遍历\尾递归优化\分治法实现 )
LeetCode题目104: 二叉树的最大深度(递归\迭代\层序遍历\尾递归优化\分治法实现 )
LeetCode题目104: 二叉树的最大深度(递归\迭代\层序遍历\尾递归优化\分治法实现 )
|
1月前
|
算法
【经典LeetCode算法题目专栏分类】【第11期】递归问题:字母大小写全排列、括号生成
【经典LeetCode算法题目专栏分类】【第11期】递归问题:字母大小写全排列、括号生成
|
1月前
|
存储 算法 数据挖掘
力扣173题:二叉搜索树迭代器(含模拟面试)
力扣173题:二叉搜索树迭代器(含模拟面试)
|
1月前
|
存储 SQL 算法
LeetCode题目100:递归、迭代、dfs使用栈多种算法图解相同的树
LeetCode题目100:递归、迭代、dfs使用栈多种算法图解相同的树
|
1月前
|
存储 算法 数据可视化
LeetCode 题目 97:动态规划、递归到广度优先搜索BFS 实现交错字符串
LeetCode 题目 97:动态规划、递归到广度优先搜索BFS 实现交错字符串
|
1月前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-2
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
|
1月前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-1
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题