day21 代码回想录 二叉搜索树的最小绝对差&二叉搜索树中的众数&二叉树的最近公共祖先

大纲

● 530.二叉搜索树的最小绝对差
● 501.二叉搜索树中的众数
● 236. 二叉树的最近公共祖先

530.二叉搜索树的最小绝对差

题目:530.二叉搜索树的最小绝对差
本题需要验证二叉搜索树的节点间的最小差,注意是叶子节点的,
思路是中序遍历得到有序数组,遍历数组更新最小值,代码如下:

void inorderReverse(TreeNode* root, vector<int>& ret) {
    if (!root) return;

    inorderReverse(root->left, ret);
    ret.push_back(root->val);
    inorderReverse(root->right, ret);
}

int minAbsValue(TreeNode* root) {
    vector<int> ret;
    inorderReverse(root, ret);
    int min = INT_MAX;
    // 判断有序
    for (int i = 1; i < ret.size(); ++i) {
        if (ret[i] - ret[i - 1] < min)
            min = ret[i] - ret[i - 1];
    }
    return min;
}

501.二叉搜索树中的众数

题目:501.二叉搜索树中的众数


// 二叉树的众数

// 递归参数:当前统计次数 最大统计次数
// 使用中序遍历
TreeNode* pre = nullptr;
void inorderCalc(TreeNode* root, int curCount, int maxCount, vector<int>& ret)
{
    if (!root) return;

    inorderCalc(root->left, curCount, maxCount, ret);
    // 处理
    if (pre) {
        if (pre->val == root->val) {
            curCount++;
        } else {
            if (curCount > maxCount) {
                ret.clear();
                ret.push_back(pre->val);
                maxCount = curCount;
            }
            else if (curCount == maxCount) { // 特别注意点
                ret.push_back(pre->val);
            }
            curCount = 1;
        }
    } else {
        curCount = 1;
    }

    pre = root;
    inorderCalc(root->right, curCount, maxCount, ret);
}

// 没有处理到当最后两个节点一致时的情况
// 没有想清楚递归单层的循环体内容

236. 二叉树的最近公共祖先

题目:236. 二叉树的最近公共祖先

// 找到公共祖先
// 需要找到根节点到p q节点的最短路径,最后正向比较最短路径,找到最后一个相同值的节点
// 使用前序遍历
void preOrderReverse(TreeNode* root, TreeNode* p, vector<TreeNode*>& path) {
    if (!root) return;
    if (root== p) {
        path.push_back(root);
        return;
    }
    path.push_back(root);
    preOrderReverse(root->left, p, path);
    preOrderReverse(root->right, p, path);
    path.pop_back();
}

// O(n)
TreeNode* sameParent(TreeNode* root, TreeNode* p, TreeNode* q) {
    if (!root) return root;
    vector<TreeNode*> path1, path2;
    preOrderReverse(root, p, path1);

    preOrderReverse(root, q, path2);

    int i = 0;
    while (i < path1.size() && i < path2.size()) {
        if (path1[i] != path2[i])
            break;
    }
    if (i < path1.size() && i < path2.size())
        return path1[i - 1];

    return nullptr;
}

// 二叉搜索树的公共祖先
// 思路:遇到第一个在[p,q]之间的数,就是公共祖先

// 递归参数返回值
// 递归结束条件:
// 单层循环
TreeNode* binaryTreeParent(TreeNode* root, TreeNode* p, TreeNode* q)
{
    if (!root) return nullptr;

    if (root->val > p->val && root->val < q->val)
        return root;

    TreeNode* pRet = binaryTreeParent(root->left, p, q);
    TreeNode* qRet = binaryTreeParent(root->right, p, q);

    return pRet ? pRet : qRet;

}

TreeNode* bSameParent(TreeNode* root, TreeNode* p, TreeNode* q)
{
    return binaryTreeParent(root, p, q);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

love_0_love

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值