剑指 Offer 68 - I. 二叉搜索树的最近公共祖先


剑指 Offer 68 - I. 二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树:  root = [6,2,8,0,4,7,9,null,null,3,5]

示例 1:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6 
解释: 节点 2 和节点 8 的最近公共祖先是 6。

一开始的想法是用双端队列,遍历两次,第一次记录p的祖先节点,第二次记录q的祖先节点,之后进行比对
class Solution {
public:

    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        deque sp;
        deque sq;
        Pan(root, p, sp);
        Pan(root, q, sq);
        TreeNode *ans = NULL;
        while (sp.front() == sq.front()) {
            ans = sp.front();
            sp.pop_front();
            sq.pop_front();
        }
        return ans;
    }
    void Pan(TreeNode* root, TreeNode* p, deque &sp) {
        if (root == NULL)
            return;
        if (!sp.empty()&&sp.back()==p) {
            return;
        }
        else {
            sp.emplace_back(root);
            Pan(root->left, p, sp);
            Pan(root->right, p, sp);
        }

        if (sp.back() != p) {
            sp.pop_back();
        }
    }
};

后面看了解法是。发现自己忽略了这是个搜索树

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        TreeNode* ancestor = root;
        while (true) {
            if (p->val < ancestor->val && q->val < ancestor->val) {
                ancestor = ancestor->left;
            }
            else if (p->val > ancestor->val && q->val > ancestor->val) {
                ancestor = ancestor->right;
            }
            else {
                break;
            }
        }
        return ancestor;
    }
};