- 二叉搜索树中的众数
给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。
假定 BST 有如下定义:
结点左子树中所含结点的值小于等于当前结点的值
结点右子树中所含结点的值大于等于当前结点的值
左子树和右子树都是二叉搜索树
例如:
给定 BST [1,null,2,2],
1
2
/
2
返回[2].
提示:如果众数超过1个,不需考虑输出顺序
进阶:你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)
方法一:使用unordered_map存储遍历结果并记录次数,将结果转到vector中,排序,遍历比较得出答案。
unordered_map<int, int> map;
vector<int> ans;
void dfs(TreeNode* root)
{
if(root == NULL) return;
map[root->val]++; //遍历记录每个元素
dfs(root->left);
dfs(root->right);
}
bool static cmp(pair<int, int>& a, pair<int, int>& b) { return a.second > b.second; }//自定义比较函数
vector<int> findMode(TreeNode* root) {
if(root == NULL) return ans;
dfs(root);
vector<pair<int, int>> vec(map.begin(), map.end());
sort(vec.begin(), vec.end(), cmp);
ans.push_back(vec[0].first);
for(int i = 1; i < vec.size(); i++)
{
if(vec[i].second == vec[0].second) ans.push_back(vec[i].first);
else break;
}
return ans;
}
方法二:利用二叉排序树的性质,声明两个指针或是两个变量来记录中序遍的当前结果和上一个结果,如果某个元素重复出现,纪录其出现次数,与最大次数比较,要是相等,则记录当前数字。如果大于,则更新最大次数和答案数组。
List<Integer> mList = new ArrayList<>();
int curent = 0;
int count = 0;
int maxCount = 0;
public int[] findMode(TreeNode root) {
inOrderTraversal(root);
int[] res = new int[mList.size()];
//把集合list转化为数组
for (int i = 0; i < mList.size(); i++) {
res[i] = mList.get(i);
}
return res;
}
//非递归方式
public void inOrderTraversal(TreeNode tree) {
Stack<TreeNode> stack = new Stack<>();
while (tree != null || !stack.isEmpty()) {
while (tree != null) {
stack.push(tree);
tree = tree.left;
}
if (!stack.isEmpty()) {
tree = stack.pop();
int nodeValue = tree.val;
if (nodeValue == curent) {
//如果节点值等于curent,count就加1
count++;
} else {
//否则,就表示遇到了一个新的值,curent和count都要
//重新赋值
curent = nodeValue;
count = 1;
}
if (count == maxCount) {
//如果count == maxCount,就把当前节点加入到集合中
mList.add(nodeValue);
} else if (count > maxCount) {
//否则,当前节点的值重复量是最多的,直接把list清空,然后
//把当前节点的值加入到集合中
mList.clear();
mList.add(nodeValue);
maxCount = count;
}
tree = tree.right;
}
}
}
本文介绍了一种从二叉搜索树(BST)中找出所有出现频率最高的元素(众数)的方法。提供了两种实现思路:一是使用unordered_map进行元素计数后排序;二是采用非递归中序遍历,通过比较相邻节点来计数。
1273

被折叠的 条评论
为什么被折叠?



