题目:
给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。
如果树中有不止一个众数,可以按 任意顺序 返回。
假定 BST 满足如下定义:
结点左子树中所含节点的值 小于等于 当前节点的值
结点右子树中所含节点的值 大于等于 当前节点的值
左子树和右子树都是二叉搜索树
方法一:
前面有一个题目跟这个思路是一模一样的:
如果不是二叉搜索树,最直观的方法一定是把这个树都遍历了,用map统计频率,把频率排个序,最后取前面高频的元素的集合。
代码:
class Solution {
public:
void search(TreeNode* node, unordered_map<int, int>& m){
if(node == nullptr) return ;
++m[node->val];
search(node->left,m);
search(node->right,m);
}
bool static cmp(const pair<int, int>a,const pair<int, int>b){
return a.second > b.second;
}
vector<int> findMode(TreeNode* root) {
unordered_map<int,int>m;
search(root, m);
vector<int>result;
vector<pair<int,int>>v(m.begin(),m.end());
sort(v.begin(), v.end(), cmp);
result.push_back(v[0].first);
for(int i = 1; i < v.size(); ++i){
if(v[i].second == v[0].second) result.push_back(v[i].first);
}
return result;
}
};
下面两种节点为空的表示都可用:
if(root == nullptr)
if( !root )
方法二:
用中序遍历即将树转换成一个递增数组的形式,然后只需要记录每个数出现的次数即可,通过当出现了更大的次数就清空结果集然后放入新的值。(此时就不需要用map来记录了)
class Solution {
public:
TreeNode* pre = nullptr;
int count = 0; //当前频率
int maxcount = 0;//最大频率
vector<int>v;
void modefind (TreeNode* cur){
if(!cur) return ;
modefind(cur->left);
if(!pre) count = 1;
else if (pre->val == cur->val) count++;
else count = 1;
pre = cur;
if(count == maxcount) {
v.push_back(cur->val);
}
if(count > maxcount){
maxcount = count;
v.clear();
v.push_back(cur->val);
}
modefind(cur->right);
}
vector<int> findMode(TreeNode* root) {
modefind(root);
return v;
}
};
方法三:
通过中序遍历,迭代
class Solution {
public:
vector<int> findMode(TreeNode* root) {
stack<TreeNode*> st;
TreeNode* cur = root;
TreeNode* pre = NULL;
int maxCount = 0; // 最大频率
int count = 0; // 统计频率
vector<int> result;
while (cur != NULL || !st.empty()) {
if (cur != NULL) { // 指针来访问节点,访问到最底层
st.push(cur); // 将访问的节点放进栈
cur = cur->left; // 左
} else {
cur = st.top();
st.pop(); // 中
if (pre == NULL) { // 第一个节点
count = 1;
} else if (pre->val == cur->val) { // 与前一个节点数值相同
count++;
} else { // 与前一个节点数值不同
count = 1;
}
if (count == maxCount) { // 如果和最大值相同,放进result中
result.push_back(cur->val);
}
if (count > maxCount) { // 如果计数大于最大值频率
maxCount = count; // 更新最大频率
result.clear(); // 很关键的一步,不要忘记清空result,之前result里的元素都失效了
result.push_back(cur->val);
}
pre = cur;
cur = cur->right; // 右
}
}
return result;
}
};