二叉树的众数问题

如果给定一棵二叉树,要找到二叉树中的所有众数(出现频率最高的元素)。

一、普通二叉树的众数

要统计出现的次数,一般使用到的是map中的unordered_map,因为不需要有序,也不需要有重复的元素,其key值一般是元素的值,value一般是元素出现的次数,这个只要遍历一遍二叉树就能得到unordered_map了;

关键是遍历得到它之后怎样做处理:

1 得到的map里放的是key(元素)和value(元素出现的个数),是按照二叉树遍历的顺序放进去的,如果不是二叉搜索树的中序遍历,那就是无序的,要在这个无序的map中找到出现频率最高的key(元素),也就是找到value值最大的所有元素,以下我总结几种方法,其实懂的人可能觉得很简单,因为我对于map的迭代操作不熟练,所以用来记录一下,勿怪。

  (1)我们新创建一个vector<pair<int, int>>,用map初始化它,然后我们需要先遍历一遍这个vector,找到value的最大值,再遍历一遍,找到这个value对应的所有元素放进结果集中。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
private:
    void searchBST(TreeNode* root, unordered_map<int, int>& map) {
        if (root == nullptr)
            return;
        map[root->val]++;
        searchBST(root->left, map);
        searchBST(root->right, map);
        return;
    }
public:
    vector<int> findMode(TreeNode* root) {
        //统计出现次数的一般用map来统计,将统计完的map转换成vector<pair<int, int>> ,利用其特点给频率进行sort排序,第一个肯定是最大的频率,检查后面还有没有跟这个频率一样的频率,记录到结果集中
        unordered_map<int, int> map;//key:元素 value:出现频率
        vector<int> result;
        if (root == nullptr)
            return result;
        searchBST(root, map);//得到的map是统计每个节点值出现的次数
        
        /*****************代码的区别在这里*******************/
        vector<pair<int, int>> vec(map.begin(), map.end());
        int maxValue = INT_MIN;//记录value的最大值
        for (int i=0; i<vec.size(); i++) {
            maxValue = max(maxValue, vec[i].second);
        }
        //以上得到了value的最大值
        for (int i=0; i<vec.size(); i++) {
            if(vec[i].second == maxValue)
                result.push_back(vec[i].first);
        }

        return result;
    }
};

  (2)直接用map迭代器进行迭代

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
private:
    void searchBST(TreeNode* root, unordered_map<int, int>& map) {
        if (root == nullptr)
            return;
        map[root->val]++;
        searchBST(root->left, map);
        searchBST(root->right, map);
        return;
    }
public:
    vector<int> findMode(TreeNode* root) {
        //统计出现次数的一般用map来统计,将统计完的map转换成vector<pair<int, int>> ,利用其特点给频率进行sort排序,第一个肯定是最大的频率,检查后面还有没有跟这个频率一样的频率,记录到结果集中
        unordered_map<int, int> map;//key:元素 value:出现频率
        vector<int> result;
        if (root == nullptr)
            return result;
        searchBST(root, map);//得到的map是统计每个节点值出现的次数
        
        /*****************代码的区别在这里*******************/
        unordered_map<int, int>::iterator it;//创建一个迭代器
        int maxValue = INT_MIN;//记录value的最大值
        for (it = map.begin(); it != map.end(); it++) {
            maxValue = max(maxValue, (*it).second);
        }
        //以上得到了value的最大值
        for (it = map.begin(); it != map.end(); it++) {
            if((*it).second == maxValue)
                result.push_back((*it).first);
        }

        return result;
    }
};

2 得到的map是key 和 value一一对应的,我们可以创建vector<pair<int, int>>来将map复制过来,然后对这个vector进行sort排序,按照value从大到小的顺序排序,排序好之后,value最大也就是出现次数最多的元素肯定排在前面,遍历一次,将他们加入结果集即可。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
private:
    void searchBST(TreeNode* root, unordered_map<int, int>& map) {
        if (root == nullptr)
            return;
        map[root->val]++;
        searchBST(root->left, map);
        searchBST(root->right, map);
        return;
    }
    bool static cmp(const pair<int, int>& a, const pair<int, int>& b) {
        return a.second > b.second;
    }
public:
    vector<int> findMode(TreeNode* root) {
        //统计出现次数的一般用map来统计,将统计完的map转换成vector<pair<int, int>> ,利用其特点给频率进行sort排序,第一个肯定是最大的频率,检查后面还有没有跟这个频率一样的频率,记录到结果集中
        unordered_map<int, int> map;//key:元素 value:出现频率
        vector<int> result;
        if (root == nullptr)
            return result;
        searchBST(root, map);//得到的map是统计每个节点值出现的次数
        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;
    }
};

二、求二叉搜索树中的所有众数

二叉搜索树也是普通的二叉树,当前可以按照普通二叉树的思路和方法求解,但是二叉搜索树具有 中序遍历 有序的特性,应用这个特性,能找到更高效的方法。

可以通过一次遍历得到结果,需要pre指针来记录前一个节点,需要count来统计频率,需要maxCount来表示最大频率,还需要一个结果集在存放结果。因为是全部遍历,所以递归函数不需要返回值

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
private:
    vector<int> result;//结果集
    int count = 0;//统计频率
    int maxCount = 0;//最大频率
    TreeNode* pre = nullptr;//记录前一个节点,与当前节点进行比较
    void searchBST(TreeNode* root) {
        if (root == nullptr)
            return;
        searchBST(root->left);//
        if (pre == nullptr)
            count = 1;//说明是第一个节点
        else if (pre->val == root->val)
            count++;
        else
            count = 1;//如果前一个跟当前不相等,清空count频率计数器
        pre = root;
        if (count == maxCount) {
            result.push_back(root->val);
        }
        if (count > maxCount) {//如果不是最大频率,就要清空result结果集,将更大的放进去
            maxCount = count;
            result.clear();
            result.push_back(root->val);
        }
        searchBST(root->right);//
        return;
    }
public:
    vector<int> findMode(TreeNode* root) {
        //二叉搜索树的中序遍历相当于一个有序数组,在一个有序数组中找出所有的众数,一次遍历就能解决
        result.clear();
        searchBST(root);
        return result;
    }
};

 

posted @ 2020-12-15 12:55  不妨不妨,来日方长  阅读(266)  评论(0编辑  收藏  举报