501. 二叉搜索树中的众数
题目链接:
给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。
假定 BST 有如下定义:
-
结点左子树中所含结点的值小于等于当前结点的值
-
-
左子树和右子树都是二叉搜索树
例如: 给定 BST [1,null,2,2]
,
1
\
2
/
2
返回[2]
.
提示:如果众数超过1个,不需考虑输出顺序
进阶:你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)
解题思路
如果该数只是普通的二叉树,那最简单的方法就是遍历这棵树,并用 map 统计频率,最后对频率进行排序,取出频率高的元素集合即可。但需要注意:C++中如果使用std::map或者std::multimap可以对key排序,但不能对value排序。所以需要将map转化数组即vector,再进行排序,当然vector里面放的也是pair<int, int>
类型的数据,第一个int为元素,第二个int为出现频率。
二叉搜索树是中序遍历有序的二叉树,所以可以将二叉搜索树的中序遍历结果存入一个数组中,再对数组中相邻两个元素作比较,最后输出频率高的元素的集合。
这里我们考虑不适用额外空间的方法,直接对树进行操作。关键点就在于要将中序遍历中 当前节点的 前一个节点 记录下来。可以参考
方法一:递归
代码
C++
// 递归 class Solution { public: int maxFre = 0; int curFre = 0; vector<int> maxVec; TreeNode* preNode = nullptr; void traversal(TreeNode* curNode) { if (curNode == nullptr) return; traversal(curNode->left); // 左 //处理频率 if (preNode == nullptr) { curFre = 1; } else if (curNode->val == preNode->val) { curFre++; } else { curFre = 1; } // 将频率大的放入数组中 if (curFre > maxFre) { maxFre = curFre; // 这里会重新给 maxFre 赋值 maxVec.clear(); maxVec.push_back(curNode->val); } else if (curFre == maxFre) { maxVec.push_back(curNode->val); } preNode = curNode; traversal(curNode->right); // 右 } vector<int> findMode(TreeNode* root) { maxFre = 0; curFre = 0; preNode = nullptr; maxVec.clear(); traversal(root); return maxVec; } };
JavaScript
// 递归 var findMode = function(root) { let curFre = 0; let maxFre = 0; let maxVec = []; let preNode = null; const traversal = (curNode) => { if (curNode === null) return; traversal(curNode.left); if (preNode === null) { curFre = 1; } else if (preNode.val === curNode.val) { curFre++; } else { curFre = 1; } if (curFre > maxFre) { maxFre = curFre; maxVec = []; maxVec.push(curNode.val); } else if (curFre === maxFre) { maxVec.push(curNode.val); } preNode = curNode; traversal(curNode.right); } traversal(root); return maxVec; };
方法二:迭代
代码
C++
// 迭代(中序遍历) class Solution2 { public: vector<int> findMode(TreeNode* root) { int maxFre = 0; int curFre = 0; vector<int> maxVec; TreeNode* preNode = nullptr; TreeNode* curNode = root; stack<TreeNode*> nodeSta; while (curNode || !nodeSta.empty()) { if (curNode) { // 左 nodeSta.push(curNode); curNode = curNode->left; } else { curNode = nodeSta.top(); nodeSta.pop(); // 中 //处理频率 if (preNode == nullptr) { curFre = 1; } else if (curNode->val == preNode->val) { curFre++; } else { curFre = 1; } // 将频率大的放入数组中 if (curFre > maxFre) { maxFre = curFre; // 这里会重新给 maxFre 赋值 maxVec.clear(); maxVec.push_back(curNode->val); } else if (curFre == maxFre) { maxVec.push_back(curNode->val); } preNode = curNode; //右 curNode = curNode->right; } } return maxVec; } };
JavaScript
// 迭代 var findMode = function(root) { let curFre = 0; let maxFre = 0; let maxVec = []; let preNode = null; let nodeSta = []; let curNode = root; while(curNode || nodeSta.length != 0) { if (curNode) { nodeSta.push(curNode); curNode = curNode.left; } else { curNode = nodeSta.pop(); if (preNode === null) { curFre = 1; } else if (preNode.val === curNode.val) { curFre++; } else { curFre = 1; } if (curFre > maxFre) { maxFre = curFre; maxVec = []; maxVec.push(curNode.val); } else if (curFre === maxFre) { maxVec.push(curNode.val); } preNode = curNode; curNode = curNode.right; } } return maxVec; };