题目:
给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。如果树中有不止一个众数,可以按 任意顺序 返回。假定 BST 满足如下定义:
- 结点左子树中所含节点的值 小于等于 当前节点的值
- 结点右子树中所含节点的值 大于等于 当前节点的值
- 左子树和右子树都是二叉搜索树
示例:
- 输入: r o o t = [ 4 , 2 , 7 , 1 , 3 ] , v a l = 2 root = [4,2,7,1,3], val = 2 root=[4,2,7,1,3],val=2
- 输出: [ 2 , 1 , 3 ] [2,1,3] [2,1,3]
解题思路一:
利用哈希表,将整棵树遍历一遍,统计元素出现的频率,然后对哈希表排序,再取出频率最高的若干元素加入结果集中。
class Solution {
public:
unordered_map<int, int> hash;
void dfs(TreeNode* cur){
if(cur == NULL) return;
hash[cur->val] ++;
dfs(cur->left);
dfs(cur->right);
return;
}
bool static cmp(const pair<int, int>& a, const pair<int, int>& b){
return a.second > b.second;
}
vector<int> findMode(TreeNode* root) {
vector<int> res;
if(root == NULL) return res;
dfs(root);
vector<pair<int, int>> vec(hash.begin(), hash.end());
sort(vec.begin(), vec.end(), cmp); // 给频率排序
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);
else break;
}
return res;
}
};
解题思路二:
利用二叉搜索树的特性来判断。由于二叉搜索树的中序遍历是有序的,因此定义两个指针pre
和cur
,pre
指向前一个元素,cur
为当前元素,比较pre->val
与cur->val
是否相同。统计频率。
-
确定递归函数的参数和返回值:
res
记录结果,cnt
是当前计数,maxCnt
是最大计数,pre
指向前一个元素。vector<int> res; int maxCnt = 0, cnt = 0; TreeNode* pre = NULL; void dfs(TreeNode* cur)
-
确定终止条件:
如果当前节点为空,返回。if(cur == NULL) return;
-
确定单层递归的逻辑:
采用中序遍历,由于二叉搜索树的中序遍历是有序的,因此利用pre
指针指向前一个元素,没递归一层,让前一个元素值与当前元素值作比较,若相等则将cnt++
,否则将cnt
置1
,当cnt==maxCnt
时,加入结果集中。dfs(cur->left); // 左 if(pre == NULL){ //中 cnt = 1; } else if (pre->val == cur->val){ cnt++; } else{ cnt = 1; } pre = cur; if(cnt == maxCnt) res.push_back(cur->val); if(cnt > maxCnt){ maxCnt = cnt; res.clear(); res.push_back(cur->val); } dfs(cur->right); // 右 return;
C++版整体代码
class Solution {
public:
vector<int> res;
int maxCnt = 0, cnt = 0;
TreeNode* pre = NULL;
void dfs(TreeNode* cur){
if(cur == NULL) return;
dfs(cur->left); // 左
if(pre == NULL){ //中
cnt = 1;
} else if (pre->val == cur->val){
cnt++;
} else{
cnt = 1;
}
pre = cur;
if(cnt == maxCnt) res.push_back(cur->val);
if(cnt > maxCnt){
maxCnt = cnt;
res.clear();
res.push_back(cur->val);
}
dfs(cur->right); // 右
return;
}
vector<int> findMode(TreeNode* root) {
dfs(root);
return res;
}
};