给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。
如果树中有不止一个众数,可以按 任意顺序 返回。
假定 BST 满足如下定义:
结点左子树中所含节点的值 小于等于 当前节点的值
结点右子树中所含节点的值 大于等于 当前节点的值
左子树和右子树都是二叉搜索树
示例 1:
输入:root = [1,null,2,2]
输出:[2]
思路:二叉搜索树,中序遍历是有序的,所以中序遍历二叉树,相同的值一定相邻,如果当前节点与上一个节点值相同,计数器+1;不同,计数器置1。统计每个值出现的次数,并把当前出现次数最多的值加入结果集,记录该值出现的次数。遇见出现次数更多的值,更新结果集,遇见与出现次数最多的相同的值,把该值加入结果集。
递归法:
class Solution { //501. 二叉搜索树中的众数 递归法
public:
vector<int> result;
int count = 1; //记录每个值出现的次数
int maxVal = INT_MIN; //记录众数出现的次数
TreeNode* pre = nullptr; //上一个节点
void traversal(TreeNode* root) {
if (root == nullptr) return;
traversal(root->left); //左
if (pre == nullptr) { //先把根节点放进结果集
result.push_back(root->val);
maxVal = 1;
}
if (pre != nullptr) { //中
if (pre->val == root->val) { //当前元素值和前一个元素值相等时,计数+1,如果此时maxVal与count相等,在结果集里加入新的元素pre->val
count++;
if (maxVal == count) {
result.push_back(pre->val);
}
}
else { //当前元素值和前一个元素值不相等,说明前一个值已经统计完,重新开始计数,令count=1,如果此时maxVal=count,将当前节点值加入结果集
count = 1;
if (maxVal == count) {
result.push_back(root->val);
}
}
if (maxVal < count) { //在遍历中,如果count>maxVal,说明之前找的都不是众数,就将整个结果集清空,加入新的元素值pre->val
result.clear();
maxVal = count;
result.push_back(pre->val);
}
}
pre = root; //更新上一个节点
traversal(root->right); //右
}
vector<int> findMode(TreeNode* root) {
traversal(root);
return result;
}
};
迭代法:
class Solution { //501. 二叉搜索树中的众数 迭代法
public:
vector<int> findMode(TreeNode* root) {
stack<TreeNode*> stk;
vector<int> result;
int count = 1; //记录每个值出现的次数
int maxVal = INT_MIN; //记录众数出现的次数
TreeNode* pre = nullptr; //上一个节点
TreeNode* cur = root;
while (cur != nullptr || !stk.empty()) {
if (cur != nullptr) {
stk.push(cur); //将访问到的节点加入栈
cur = cur->left;
}
else { //中
cur = stk.top();
stk.pop();
if (pre == nullptr) { //先把根节点放进结果集
result.push_back(cur->val);
maxVal = 1;
}
if (pre != nullptr) {
if (pre->val == cur->val) { //当前元素值和前一个元素值相等时,计数+1,如果此时maxVal与count相等,在结果集里加入新的元素pre->val
count++;
if (maxVal == count) {
result.push_back(pre->val);
}
}
else { //当前元素值和前一个元素值不相等,说明前一个值已经统计完,重新开始计数,令count=1,如果此时maxVal=count,将当前节点值加入结果集
count = 1;
if (maxVal == count) {
result.push_back(cur->val);
}
}
if (maxVal < count) { //在遍历中,如果count>maxVal,说明之前找的都不是众数,就将整个结果集清空,加入新的元素值pre->val
result.clear();
maxVal = count;
result.push_back(pre->val);
}
}
pre = cur; //更新上一个节点
cur = cur->right; //右
}
}
return result;
}
};