其他分享
首页 > 其他分享> > LeetCode基础_树_祖先系列

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