LeetCode基础_树_祖先系列
作者:互联网
[235] 二叉搜索树的最近公共祖先
思路比较简单,根据二叉搜索树性质,要找的node的val只要 p或q->val <= node->val <= q或p->val
class Solution {
public:
TreeNode *recurse(TreeNode *curr, TreeNode *p, TreeNode *q) {
if (curr->val < p->val && curr->val < q->val)
return recurse(curr->right, p, q);
else if (curr->val > p->val && curr->val > q->val)
return recurse(curr->left, p, q);
else
return curr;
}
TreeNode *lowestCommonAncestor(TreeNode *root, TreeNode *p, TreeNode *q) {
return recurse(root, p, q);
}
};
[236] 二叉树的最近公共祖先
简单思路:On的空间复杂度来记录根节点到p和q的路径,遍历从根到两者的路径一直到不同为止。
优化思路:递归,空间优化到O1
遇上题类似,只要左树和右树都存在p和q,即终止,否则继续向左树或右树走
通过自上而下递归,进行优化后,无需重复遍历。
这道题优化前为 先递归判断条件 后递归往下找结果,
而优化后改变成 先递归往下找结果 后直接判断条件并return。
代码如下:
class Solution {
public:
TreeNode *recurse(TreeNode *curr, TreeNode *p, TreeNode *q) {
if (!curr)
return nullptr; //可以缩写,但为保证可读性
if (curr == p || curr == q) //curr踩中某个点
return curr;
TreeNode *left = recurse(curr->left, p, q);//在此步骤向下递归返回的就是符合条件的值
TreeNode *right = recurse(curr->right, p, q);
if (left && right) //左右都不为null,说明一边有p 一边有q,直接返回
return curr;
else if (left) //只有一边有p和q,另一边没有
return left; //这里经过了优化,因为上面的left已经递归过了,已经拿到了正确的结果
//return recurse(curr->left, p, q);//优化前
else if (right)
return right; //同上,优化,不做重复递归
return nullptr;
}
TreeNode *lowestCommonAncestor(TreeNode *root, TreeNode *p, TreeNode *q) {
return recurse(root, p, q);
}
};
[572] 另一个树的子树
class Solution {
public:
bool isSameTree(TreeNode *s, TreeNode *t) {//递归判断以当前节点为根的树是否相同
if (!s && !t)
return true;
return s && t && (s->val == t->val) && isSameTree(s->left, t->left) && isSameTree(s->right, t->right) ? true : false;
}
void recurse(TreeNode *s, TreeNode *t, bool &find) {//递归判断每个s点做为根的树于t树相同
if (find || !s)
return;
if (s->val == t->val)
find = isSameTree(s, t);
recurse(s->left, t, find);
recurse(s->right, t, find);
}
bool isSubtree(TreeNode *s, TreeNode *t) {//主函数,为了减枝设置find
if (!t)
return true;
bool find = false;
recurse(s, t, find);
return find;
}
};
[508] 出现次数最多的子树元素和
class Solution {
public:
map<int, int> sum_; //每一个子树的值,该值出现的次数
int recurse(TreeNode *curr, int &tree_sum) {
if (!curr)
return 0;
int left_sum = recurse(curr->left, tree_sum); //左子树和
int right_sum = recurse(curr->right, tree_sum); //右子树和
int now_sum = curr->val + left_sum + right_sum; //以当前节点为根的树和
sum_[now_sum]++; //当前和出现次数+1
tree_sum += curr->val; //总树和+当前节点值
return now_sum;
}
vector<int> findFrequentTreeSum(TreeNode *root) {
int tree_sum = 0, max = -1; //树总和,最大次数
recurse(root, tree_sum);
vector<int> ret;
for (pair p : sum_)
if (p.second == max)
ret.push_back(p.first);
else if (p.second > max) {
max = p.second;
ret.clear();
ret.push_back(p.first);
}
return ret;
}
};
标签:TreeNode,val,祖先,sum,recurse,return,curr,LeetCode,系列 来源: https://www.cnblogs.com/Shaw99/p/13335920.html