二叉樹的眾數問題
如果給定一棵二叉樹,要找到二叉樹中的所有眾數(出現頻率最高的元素)。
一、普通二叉樹的眾數
要統計出現的次數,一般使用到的是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; } };