17. 二叉搜索树的最小绝对值和众数

📃 题目一描述

题目链接:二叉搜索树的最小绝对值

image-20220607012550884

🔔 解题思路

解法一:安装顺序遍历相邻作差,每一次保留上一个遍历的值,和当前遍历的值进行相减;

class Solution {
public:
    int res = INT_MAX;
    int num = INT_MIN;
    int getMinimumDifference(TreeNode* root) {
        getNum(root);
        return res;
    }
    void getNum(TreeNode* root) {
        if (root == nullptr) return;

        getNum(root->left);
        if (num != INT_MIN) {
            res = min(root->val - num, res);
        }
        num = root->val;
        getNum(root->right);
    }
};

解法一换种版本:采用指针记录前面的值

class Solution {
private:
    int res = INT_MAX;
    TreeNode* pre;
public:
    void searchBST(TreeNode* cur) {
        if (cur == nullptr) return;
        searchBST(cur->left);
        // 中序
        if (pre != nullptr) {
            res = min(res, cur->val - pre->val);
        }
        pre = cur;
        searchBST(cur->right);
    }
    int getMinimumDifference(TreeNode* root) {
        searchBST(root);
        return res;
    }
};

解法二:采用迭代法

class Solution {
public:
    int minDiffInBST(TreeNode* root) {
        int res = INT_MAX;
        stack<TreeNode*> st;
        TreeNode* pre = nullptr;
        TreeNode* cur = root;
        while (cur || !st.empty()) {
            if (cur != nullptr) {
                st.push(cur);
                cur = cur->left;
            }
            else {
                cur = st.top(); st.pop();
                if (pre != nullptr) {
                    res = min(res, cur->val - pre->val);
                }
                pre = cur;
                cur = cur->right;
            }
        }
        return res;
    }
};

💥 复杂度分析

  • 时间复杂度:O(n);
  • 空间复杂度:O(n);

📃 题目二描述

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

image-20220608002633839

🔔 解题思路

解法一:二叉树的通用解法,用一个map来记录每个数字出现的次数,map再从大到小排序,拿前面大的值即可

class Solution {
public:
    unordered_map<int, int> mp;
    void searchBST(TreeNode* root) {
        if (root == nullptr) return;
        // 中序遍历
        searchBST(root->left);
        mp[root->val]++;
        searchBST(root->right);
    }
    bool static cmp(pair<int, int> &a, pair<int, int> &b) { //从大到小排序
        return a.second > b.second;
    }
    vector<int> findMode(TreeNode* root) {
        searchBST(root);
        vector<int> res;
        vector<pair<int, int>> vec(mp.begin(), mp.end()); //构建vec
        sort(vec.begin(), vec.end(), cmp);
        res.push_back(vec[0].first);
        for (int i = 1; i < vec.size(); i++) {
            if (vec[i].second == vec[0].second) res.push_back(vec[i].first);
            else break;
        }
        return res;
    }
};

解法二:利用BST树的特性,中序遍历的过程中,相等的两个数是连续的,所以采用 一个maxCount记录元素最大个数,pre记录前面的指针(即可知道前面的值),count记录当前元素的个数,vector< int > res保存答案

class Solution {
private:
    int maxCount;
    int count;
    vector<int> res;
    TreeNode* pre;
public:
    void searchBST(TreeNode* root) {
        if (root == nullptr) return;
        //中序遍历
        searchBST(root->left);

        if (pre == nullptr) count = 1; //pre不存在
        else if (pre->val == root->val) count++; //pre存在 且 前后相等
        else count = 1; //pre存在 但 前后不等
        pre = root; // 更新pre节点

        if (count == maxCount) res.push_back(root->val);
        if (count > maxCount) {
            res.clear();
            res.push_back(root->val);
            maxCount = count;
        }
    
        searchBST(root->right);
    }
    vector<int> findMode(TreeNode* root) {
        searchBST(root);
        return res;
    }
};

解法三:迭代法,思想和上面的递归思想一样,可以锻炼一下二叉树迭代;

class Solution {
public:
    vector<int> findMode(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> st;
        int count = 0, maxCount = 0;
        TreeNode* pre = nullptr;
        TreeNode* cur = root;
        while (cur || !st.empty()) {
            if (cur) {
                st.push(cur);
                cur = cur->left;
            }
            else {
                cur = st.top(); st.pop();
                //中序
                if (pre == nullptr) count = 1; //pre不存在
                else if (pre->val == cur->val) count++; //pre存在 且 前后相等
                else count = 1; //pre存在 但 前后不等
                pre = cur; // 更新pre节点

                if (count == maxCount) res.push_back(cur->val);
                if (count > maxCount) {
                    res.clear();
                    res.push_back(cur->val);
                    maxCount = count;
                }

                cur = cur->right; 
            }
        }
        return res;
    }
};

💥 复杂度分析

  • 时间复杂度:O(n);
  • 空间复杂度:O(n);
posted @ 2022-06-07 01:28  D-booker  阅读(22)  评论(0编辑  收藏  举报