LeetCode501. 二叉搜索树中的众数

在这里插入图片描述


LeetCode501. 二叉搜索树中的众数


题目:

 给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。如果树中有不止一个众数,可以按 任意顺序 返回。假定 BST 满足如下定义:

  • 结点左子树中所含节点的值 小于等于 当前节点的值
  • 结点右子树中所含节点的值 大于等于 当前节点的值
  • 左子树和右子树都是二叉搜索树

示例:

在这里插入图片描述

  • 输入: r o o t = [ 4 , 2 , 7 , 1 , 3 ] , v a l = 2 root = [4,2,7,1,3], val = 2 root=[4,2,7,1,3],val=2
  • 输出: [ 2 , 1 , 3 ] [2,1,3] [2,1,3]

解题思路一:
 利用哈希表,将整棵树遍历一遍,统计元素出现的频率,然后对哈希表排序,再取出频率最高的若干元素加入结果集中。

class Solution {
public:
    unordered_map<int, int> hash;
    void dfs(TreeNode* cur){
        if(cur == NULL) return;
        hash[cur->val] ++;
        dfs(cur->left);
        dfs(cur->right);
        return;
    }
    bool static cmp(const pair<int, int>& a, const pair<int, int>& b){
        return a.second > b.second;
    }
    vector<int> findMode(TreeNode* root) {
        vector<int> res;
        if(root == NULL) return res;
        dfs(root);
        vector<pair<int, int>> vec(hash.begin(), hash.end());
        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;
    }
};

解题思路二:
 利用二叉搜索树的特性来判断。由于二叉搜索树的中序遍历是有序的,因此定义两个指针precurpre指向前一个元素,cur为当前元素,比较pre->valcur->val是否相同。统计频率。

  1. 确定递归函数的参数和返回值:
    res记录结果,cnt是当前计数,maxCnt是最大计数,pre指向前一个元素。

    vector<int> res;
    int maxCnt = 0, cnt = 0;
    TreeNode* pre = NULL;
    void dfs(TreeNode* cur)
    
  2. 确定终止条件:
    如果当前节点为空,返回。

    if(cur == NULL) return;
    
  3. 确定单层递归的逻辑:
    采用中序遍历,由于二叉搜索树的中序遍历是有序的,因此利用pre指针指向前一个元素,没递归一层,让前一个元素值与当前元素值作比较,若相等则将cnt++,否则将cnt1,当cnt==maxCnt时,加入结果集中。

    dfs(cur->left);  // 左
    if(pre == NULL){   //中
        cnt = 1;
    } else if (pre->val == cur->val){
        cnt++;
    } else{
        cnt = 1;
    }
    pre = cur;
    if(cnt == maxCnt) res.push_back(cur->val);
    if(cnt > maxCnt){
        maxCnt = cnt;
        res.clear();
        res.push_back(cur->val);
    }
    dfs(cur->right);  // 右
    return;
    

C++版整体代码

class Solution {
public:
    vector<int> res;
    int maxCnt = 0, cnt = 0;
    TreeNode* pre = NULL;
    void dfs(TreeNode* cur){
        if(cur == NULL) return;
        dfs(cur->left);  // 左
        if(pre == NULL){   //中
            cnt = 1;
        } else if (pre->val == cur->val){
            cnt++;
        } else{
            cnt = 1;
        }
        pre = cur;
        if(cnt == maxCnt) res.push_back(cur->val);
        if(cnt > maxCnt){
            maxCnt = cnt;
            res.clear();
            res.push_back(cur->val);
        }
        dfs(cur->right);  // 右
        return;
    }
    vector<int> findMode(TreeNode* root) {
        dfs(root);
        return res;
    }
};
  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值