zoukankan      html  css  js  c++  java
  • 二叉树的众数问题

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

    一、普通二叉树的众数

    要统计出现的次数,一般使用到的是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;
        }
    };
  • 相关阅读:
    第十二章 圆周率的计算问题分析
    第十一章:random库概述
    【模板】分治 FFT
    [PKUWC2018]Slay the Spire
    [PKUWC2018]随机算法
    [PKUWC2018]Minimax
    线段树合并初探
    平衡树初探
    Luogu P1613 跑路 题解报告
    CH138 兔子和兔子 题解报告
  • 原文地址:https://www.cnblogs.com/masbay/p/14137918.html
Copyright © 2011-2022 走看看