二叉树的众数问题
如果给定一棵二叉树,要找到二叉树中的所有众数(出现频率最高的元素)。
一、普通二叉树的众数
要统计出现的次数,一般使用到的是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; } };