题目
思路(递归)
在这里先回顾一下二叉树的相关知识,二叉树的四种遍历:前序遍历、中序遍历、后序遍历、层次遍历,这些算法都有递归和非递归两种,递归相对简单,非递归效率更高,时间比较长没有练习,抽时间会专门写一篇关于二叉树递归非递归的文字帮助自己回忆一下!
前序遍历:根节点---->左节点---->右节点
中序遍历:左节点---->根节点---->右节点
后序遍历:左节点---->右节点---->根节点
层次遍历:从上往下一层一层遍历
我的理解是深度优先遍历(DFS)包括前、中、后序遍历,而广度遍历(BFS)则为层次遍历(理解不对希望大家指出)
思路:将题目归纳一下,其实就是从下往上找两个节点的父节点,那么从下往上应当使用深度优先遍历,那么我们只需要在DFS中添加上两个bool值,当某个节点的值与给出的p,q相等时,该节点与其祖先节点均为true,当某个节点有两个true的时候,该节点就为我们要求的节点。
代码
/**
* 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* ans;
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
dfs(root, p, q);
return ans;
}
bool dfs(TreeNode* root, TreeNode* p, TreeNode* q){
if(root==nullptr) return false;
bool lbol = dfs(root->left, p, q);
bool rbol = dfs(root->right, p, q);
if((lbol && rbol)||((root->val == p->val || root->val == q->val) && (lbol || rbol))){
ans = root;
return true;
}
return root->val == p->val || root->val == q->val || lbol || rbol;
}
};
思路(存储父节点)
这里的思路与上面类似,只不过是使用了两个哈希表来储存p,q的祖先节点,然后求出他们最近的祖先节点,区别不大,大家看懂上面的思路就好
代码
/**
* 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:
unordered_map<int, TreeNode*> fa;
unordered_map<int, bool> vis;
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==nullptr) return nullptr;
fa[root->val] = nullptr;
dfs(root);
while(p != nullptr){
vis[p->val] = true;
p = fa[p->val];
}
while(q != nullptr){
if(vis[q->val]) return q;
q = fa[q->val];
}
return nullptr;
}
void dfs(TreeNode* root){
if(root->left != nullptr){
fa[root->left->val] = root;
dfs(root->left);
}
if(root->right != nullptr){
fa[root->right->val] = root;
dfs(root->right);
}
}
};