代码随想录算法训练营第二十一天|530.二叉搜索树的最小绝对差,501.二叉搜索树中的众数,236. 二叉树的最近公共祖先

本文介绍了在二叉搜索树中解决三个问题的思路和代码:1)计算最小绝对差,通过中序遍历并计算相邻元素差;2)寻找众数,利用哈希表统计元素出现次数或中序遍历记录频率;3)找到最近公共祖先,采用后序遍历的回溯法。
摘要由CSDN通过智能技术生成

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

题目链接:530.二叉搜索树的最小绝对差

文档讲解:代码随想录

视频讲解:二叉搜索树中,需要掌握如何双指针遍历!| LeetCode:530.二叉搜索树的最小绝对差

思路

思路一: 对二叉搜索树进行中序遍历转化为有序数组,然后计算数组相邻两两元素的绝对差。

思路二: 通过一个指针记录当前结点的前一个结点,然后进行中序遍历,计算当前结点与前一个结点的绝对差。

代码

思路一代码

class Solution {
public:
    int getMinimumDifference(TreeNode *root) {
        value.clear();
        int result = INT_MAX;
        traversal(root);
        for (int i = 1; i < value.size(); i++) {
            result = result < value[i] - value[i - 1] ? result : value[i] - value[i - 1];
        }
        return result;
    }

private:
    vector<int> value;
    void traversal(TreeNode *node) {
        if (node == NULL)
            return;
        traversal(node->left);
        value.push_back(node->val);
        traversal(node->right);
    }
};

思路二代码

class Solution {
public:
    int getMinimumDifference(TreeNode *root) {
        traversal(root);
        return result;
    }

private:
    int result = INT_MAX;
    TreeNode *pre;
    void traversal(TreeNode *node) {
        if (node == NULL)
            return;
        traversal(node->left);
        if (pre == NULL)
            pre = node;
        else {
            result = result < node->val - pre->val ? result : node->val - pre->val;
            pre = node;
        }
        traversal(node->right);
    }
};

501.二叉搜索树中的众数

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

文档讲解:代码随想录

视频讲解:不仅双指针,还有代码技巧可以惊艳到你! | LeetCode:501.二叉搜索树中的众数

思路

思路一: 遍历二叉搜索树,使用哈希表记录每个数值和出现的次数,然后根据出现的次数对数组进行排序,返回出现次数最高的值。

思路二: 中序遍历二叉搜索树,记录相同元素出现次数,与当前最大出现次数进行比较,如果等于当前最大出现次数,将该结点的值放入结果数组;如果大于当前最大出现次数,则将该结点的值放入结果数组并更新当前最大出现次数。

代码

思路一代码

class Solution {
public:
    vector<int> findMode(TreeNode *root) {
        vector<int> result;
        traversal(root);
        vector<pair<int, int>> vec(map.begin(), map.end());
        sort(vec.begin(), vec.end(), cmp);
        result.push_back(vec[0].first);
        for (int i = 1; i < vec.size(); i++) {
            if (vec[i].second == vec[0].second)
                result.push_back(vec[i].first);
            else
                break;
        }
        return result;
    }

private:
    unordered_map<int, int> map;
    void traversal(TreeNode *node) {
        if (node == NULL)
            return;
        traversal(node->left);
        map[node->val]++;
        traversal(node->right);
    }

    bool static cmp(const pair<int, int> &a, const pair<int, int> &b) {
        return a.second > b.second; // 按照频率从大到小排序
    }
};

代码随想录方法二代码

class Solution {
public:
    vector<int> findMode(TreeNode *root) {
        traversal(root);
        return result;
    }

private:
    vector<int> result;
    TreeNode *pre;
    int maxCount = 0;
    int count = 0;
    void traversal(TreeNode *node) {
        if (node == NULL)
            return;
        traversal(node->left);

        if (pre == NULL)
            count = 1;
        else if (node->val == pre->val)
            count++;
        else
            count = 1;
        pre = node;

        if (count == maxCount)
            result.push_back(node->val);

        if (count > maxCount) {
            maxCount = count;
            result.clear();
            result.push_back(node->val);
        }

        traversal(node->right);
    }
};

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

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

文档讲解:代码随想录

视频讲解:自底向上查找,有点难度! | LeetCode:236. 二叉树的最近公共祖先

思路

使用后序遍历回溯,如果一个结点的左子树出现结点p(q),并且右子树出现结点q§,则该节点为p和q的最近公共祖先。

代码

class Solution {
public:
    TreeNode *lowestCommonAncestor(TreeNode *root, TreeNode *p, TreeNode *q) {
        return traversal(root, p, q);
    }

private:
    TreeNode *traversal(TreeNode *node, TreeNode *p, TreeNode *q) {
        if (node == NULL)
            return NULL;
        if (node == q)
            return q;
        if (node == p)
            return p;

        TreeNode *left = traversal(node->left, p, q);
        TreeNode *right = traversal(node->right, p, q);

        if (left != NULL && right != NULL)
            return node;
        else if (left == NULL && right != NULL)
            return right;
        else if (left != NULL && right == NULL)
            return left;
        else
            return NULL;
    }
};
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值