这两道题不管是哪一个,核心都是基于二叉树后序遍历,核心思路是:
1、遍历到当前节点,如果它是要找的两个节点的任何一个时,返回它
2、如果当前节点为空,也就是没找到,返回空
3、每一个节点的左、右子树的深搜结果,就反映的是它左、右子树是否存在这两个节点,如果为空说明不存在,否则说明存在
如果左、右子树的深搜结果都非空,那么说明这两个节点分别在该节点的左右子树,该节点就是最小公共祖先,返回它自己
如果仅左或右某一子树非空,说明它只是某一个节点的祖先,继续返回非空的地址即可
如果全为空,说明该节点不是任何一个节点的祖先,继续返回空
题235和236的唯一区别是,235是搜索二叉树,236是普通二叉树,235需要做剪枝,即避免掉不必要的搜索,如需要找的节点的value为10和15,当前节点为20,那就不要去当前节点的右子树去查找了,因为肯定找不到的
题235代码:
class Solution {
public:
TreeNode *helper (TreeNode *cur, TreeNode *p, TreeNode *q) {
if (cur) {
if (cur == p || cur == q) {
return cur;
} else {
TreeNode *left = nullptr, *right = nullptr;
if (cur->val > p->val && cur->val > q->val) {
left = helper(cur->left, p, q);
} else if (cur->val < p->val && cur->val < q->val) {
right = helper(cur->right, p, q);
} else {
left = helper(cur->left, p, q);
right = helper(cur->right, p, q);
}
if (left && right) {
return cur;
} else if (left || right) {
return left?left:right;
} else {
return nullptr;
}
}
} else {
return nullptr;
}
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (!root || !p || !q) {
return nullptr;
}
return helper(root, p, q);
}
};
class Solution {
public:
TreeNode *helper (TreeNode *cur, TreeNode *p, TreeNode *q) {
if (cur) {
if (cur == p || cur == q) {
return cur;
} else {
TreeNode *left = helper(cur->left, p, q);
TreeNode *right = helper(cur->right, p, q);
if (left && right) {
return cur;
} else if (left || right) {
return left?left:right;
} else {
return nullptr;
}
}
} else {
return nullptr;
}
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (!root || !p || !q) {
return nullptr;
}
return helper(root, p, q);
}
};