题目链接:leetcode.
题目中说了,是一棵 二叉搜索树,,我是怎么一回事啊
二叉搜索树可以直接找出来到某个节点的路径,从后往前对比路径,第一个相同的就是公共祖先咯
O(n) O(n)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
/*
执行用时:40 ms, 在所有 C++ 提交中击败了46.08%的用户
内存消耗:22.8 MB, 在所有 C++ 提交中击败了46.40%的用户
*/
class Solution {
public:
vector<TreeNode*> findNode(TreeNode* root, TreeNode* target)
{
vector<TreeNode*> path;
TreeNode* node = root;
while(node != target)//因为是二叉搜索树所以不怕找不到,不用判node为空
{
path.push_back(node);
if(node -> val > target -> val)
{
node = node -> left;
}
else
{
node = node -> right;
}
}
path.push_back(node);
return path;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
vector<TreeNode*> p_path = findNode(root, p);
vector<TreeNode*> q_path = findNode(root, q);
//因为i从0到n,对应的是树的深度,所以相同的path节点一定深度相同
TreeNode * ans = NULL;
//i从size-1开始哦
for(int i = min(p_path.size(), q_path.size()) - 1;i >= 0;--i)
{
// cout << i << ' ' << p_path[i] -> val <<endl;
if(p_path[i] == q_path[i])
{
ans = p_path[i];
break;
}
}
return ans;
}
};
太厉害了吧!
将两次寻找路径合并起来,甚至不记录,将空间复杂度降到O(1)
如果目前node的值大于p也大于q,说明他俩的公共祖先一定比node小,
node = node -> left;
如果小于p也小于q,说明公共祖先在右子树内,所以node = node -> right;
否则,node就是p和q的最小公共祖先,一个在node的左子树里,一个在右子树里(或者甚至node就是p、q中的一个)
/*
执行用时:36 ms, 在所有 C++ 提交中击败了68.55%的用户
内存消耗:22.7 MB, 在所有 C++ 提交中击败了76.98%的用户
*/
/**
* 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) {
TreeNode* node = root;
while(true)
{
if(node->val > p-> val && node->val > q->val)
node = node->left;
else if(node->val < p-> val && node->val < q->val)
node = node->right;
else
{
break;
}
}
return node;
}
};
这里有点点不太懂,为什么先
break
再return
会比直接在里面return
来的快诶(⊙﹏⊙)