1 问题
给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。
假定 BST 有如下定义:
结点左子树中所含结点的值小于等于当前结点的值
结点右子树中所含结点的值大于等于当前结点的值
左子树和右子树都是二叉搜索树
例如:
给定 BST [1,null,2,2],
返回[2].
提示:如果众数超过1个,不需考虑输出顺序
进阶:你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)
2 解法
根据二叉搜索树中序遍历的有序性,比较前一个节点与当前节点的值,此时共有以下几种情况:
(1)前一个节点为空,则当前节点是第一个节点。
(2)当前节点值与前一个节点值相等。
(3)当前节点值与前一个节点值不等。(新的开始节点)
//若上一个节点为空,则当前节点为第一个节点 //中
if(pre == nullptr)
count = 1;
//当前节点元素与上个元素相等
else if(pre-> val == cur->val)
count++;
//当前节点元素与上个元素不等
else
count = 1;
2.1 递归法
/**
* 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 {
public:
TreeNode* pre = nullptr;
int count; //统计频率
int maxCount; //最大频率
vector<int> res;
//中序遍历
void searchBST(TreeNode* cur)
{
if(cur == nullptr)
return;
searchBST(cur->left); //左
//若上一个节点为空,则当前节点为第一个节点 //中
if(pre == nullptr)
count = 1;
//当前节点元素与上个元素相等
else if(pre-> val == cur->val)
count++;
//当前节点元素与上个元素不等
else
count = 1;
//比较count与maxCount,等于则加入数组,大于则清空数组,放入此时的元素
if(count == maxCount)
res.push_back(cur->val);
if(count > maxCount)
{
//1.更新maxCount
maxCount = count;
//2.清空结果数组
res.clear();
//3.将此时maxCount对应的当前节点元素加入结果元素
res.push_back(cur->val);
}
//更新上个节点
pre = cur;
searchBST(cur->right); //右
}
vector<int> findMode(TreeNode* root) {
searchBST(ro`在这里插入代码片`ot);
return res;
}
};
2.2 迭代法
/**
* 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 {
public:
vector<int> findMode(TreeNode* root) {
TreeNode* pre = nullptr;
TreeNode* cur = root;
stack<TreeNode*> st;
int count; //统计频率
int maxCount; //最大频率
vector<int> res;
while(cur != nullptr || !st.empty())
{
if(cur != nullptr)
{
st.push(cur);
cur = cur->left; //左
}
else
{
cur = st.top(); //中
st.pop();
if(pre == nullptr)
count = 1;
else if(pre->val == cur->val)
count++;
else
count = 1;
if(count == maxCount)
res.push_back(cur->val);
if(count > maxCount)
{
maxCount = count;
res.clear();
res.push_back(cur->val);
}
pre = cur;
cur = cur->right; //右
}
}
return res;
}
};
3 普通二叉树求众数
class Solution {
private:
void searchBST(TreeNode* cur, unordered_map<int, int>& map) { // 前序遍历
if (cur == NULL) return ;
map[cur->val]++; // 统计元素频率
searchBST(cur->left, map);
searchBST(cur->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) {
unordered_map<int, int> map; // key:元素,value:出现频率
vector<int> result;
if (root == NULL) return result;
searchBST(root, 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++) {
// 取最高的放到result数组中
if (vec[i].second == vec[0].second) result.push_back(vec[i].first);
else break;
}
return result;
}
};