题目:
给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。
假定 BST 有如下定义:
结点左子树中所含结点的值小于等于当前结点的值
结点右子树中所含结点的值大于等于当前结点的值
左子树和右子树都是二叉搜索树
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
// /*******************法一::二叉树的通用 递归 方法*******************/
// private:
// // 递归思路:根据题意,需要将整棵树都遍历一次,因此不需要返回值
// // 因为要计算频率,因此定义map,来计算出现的频次即可,
// // 这样的方法即使是非二叉搜索树也适用,先自己完成,后面在进行优化⑧~
// // key = 节点的数值, value = 该数值出现的次数
// unordered_map<int,int> mp;
// void travel(TreeNode* cur)
// {
// if(cur == nullptr)
// {
// return;
// }
// // 中序遍历 左 中 右
// // 遍历过程中允许空节点进入递归逻辑
// travel(cur->left);
// mp[cur->val]++;
// travel(cur->right);
// }
// 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中的 value 需要进行排序
// // 但是C++中,利用map或multimap可以对 key 进行排序,对value是无法排序的
// // 所以要么是把map换成vector再排序,要么不用map,直接用vector<pair<int,int>>类型
// // 别忘了 vector 也是可以放pair类型的数据的
// // // 要找出 mp 中的最大 value
// // vector<int> res; // 赋值都不知道要赋什么值了
// // int minVal = INT_MAX;
// // for(auto& it : mp)
// // {
// // // 这里判断也变得很 让人难受,这个方法行不通了
// // if(minVal > it.second)
// // {
// // minVal = it.second;
// // }
// // }
// /***************************************************************/
// travel(root);
// vector<int> res; // 记录结果值
// vector<pair<int,int>> vec{mp.begin(),mp.end()}; // 初始化
// sort(vec.begin(),vec.end(),cmp); //对pair中的第二个元素排序
// res.push_back(vec[0].first);
// for(int i=1; i<vec.size(); i++)
// {
// if(vec[i].second == vec[0].second)
// {
// res.push_back(vec[i].first);
// }
// // 因为已经按照频率排序了,所以一旦有不等于,
// // 那么后面一定是小于,所以直接break即可,不要忘记这里的break
// else
// {
// break;
// }
// }
// return res;
// }
// /**************************法二::BST 递归法************************/
// private:
// // 还需要定义一个统计频率的变量,就不用map容器了
// int count; // 统计频率
// int maxCount; // 统计最大频率
// vector<int> result;
// TreeNode* pre;
// // 本写法不用map容器
// // unordered_map<int, int> mp; // key表示节点值, value 表示出现次数
// void travel(TreeNode* cur)
// {
// if(cur == nullptr)
// {
// return;
// }
// // 中序遍历: 左 中 右
// travel(cur->left);
// /****************中节点的处理真的是精髓啊*******************************/
// // 第一part:与pre节点进行比较,处理是否相等的情况,达到对频率更新的目的
// if(pre == nullptr) // 表示第一个节点
// {
// count = 1;
// }
// else if(pre->val == cur->val) // 表示与前一个值相同
// {
// count++;
// }
// else // 表示与前一个节点值不同
// {
// count = 1;
// }
// pre = cur; // 更新上一个节点
// // 第二part:对count和maxCount的对比,以达到更新结果集合的目的
// if(count == maxCount) // 如果和maxCount相同,则放入result
// {
// result.push_back(cur->val);
// }
// if(count > maxCount) // 如果大于maxCount,则更新result和macCount
// {
// result.clear();
// maxCount = count;
// result.push_back(cur->val);
// }
// /**************************************************************/
// travel(cur->right);
// }
// public:
// vector<int> findMode(TreeNode* root)
// {
// // 注意类的成员变量在 private 里面一般只定义,不初始化
// count = 0;
// maxCount = 0;
// pre = nullptr;
// result.clear();
// travel(root);
// return result;
// }
/************************法三::迭代法***************************/
public:
vector<int> findMode(TreeNode* root)
{
int count = 0;
int maxCount = 0;
vector<int> result;
stack<TreeNode*> st;
TreeNode* pre = nullptr;
if(root == nullptr)
{
return result;
}
st.push(root);
while(!st.empty())
{
TreeNode* cur = st.top();
if(cur != nullptr)
{
// 中序遍历 压栈顺序 右 中 左
st.pop();
if(cur->right != nullptr)
{
st.push(cur->right);
}
st.push(cur);
st.push(nullptr);
if(cur->left != nullptr)
{
st.push(cur->left);
}
}
else
{
st.pop();
cur = st.top();
st.pop();
// part1 比较节点
if(pre == nullptr)
{
count = 1;
}
else if(pre->val == cur->val)
{
count++;
}
else
{
count = 1;
}
// 在节点比较结束后,不要忘记更新 pre
pre = cur;
// part2 比较频率
if(count == maxCount)
{
result.push_back(cur->val);
}
if(count > maxCount)
{
result.clear();
maxCount = count;
result.push_back(cur->val);
}
}
}
return result;
}
};