来源:https://leetcode-cn.com/problems/find-mode-in-binary-search-tree
给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。
假定 BST 有如下定义:
结点左子树中所含结点的值小于等于当前结点的值
结点右子树中所含结点的值大于等于当前结点的值
左子树和右子树都是二叉搜索树
例如:
给定 BST [1,null,2,2],

返回[2].
提示:如果众数超过1个,不需考虑输出顺序
进阶:你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)
题解:简单的思路是hash解法,根据数值绝对值取模,每次插入查一下存不存在,存在直接加,不存在插入hash节点,这样解需要额外的空间。
那么如何不使用额外的空间?
解法一(hash):
public class 二叉搜索树中的众数501 {
private long[] head = new long[100010];
private long[] next = new long[100010];
private long[] hash = new long[100010];
private long[] num = new long[100010];
private long max = -Long.MAX_VALUE;
private List<Long> vals = new ArrayList<>();
int MOD = 100010;
int top = 1;
private int find(long x){
for (long i = head[(int)((x<0?-x:x) % MOD)]; i != 0; i = next[(int)i]){
if(x == hash[(int)i]){
return (int)i;
}
}
return -1;
}
private void add(long x){
int index = find(x);
if(index > 0){
findMax(index, x);
return;
}
int i = (int)((x<0?-x:x) % MOD);
hash[top] = x;
next[top] = head[i];
head[i] = top;
findMax(top, x);
top++;
}
private void findMax(int top, long x) {
num[top]++;
if(num[top] > max){
vals.clear();
vals.add(x);
max = num[top];
}else if(num[top] == max){
vals.add(x);
}
}
public void dfs(TreeNode root) {
if(root == null){
return;
}
add(root.val);
dfs(root.left);
dfs(root.right);
}
public int[] findMode(TreeNode root) {
dfs(root);
int[] answers = new int[vals.size()];
for(int i = 0; i < vals.size(); i++){
answers[i] = vals.get(i).intValue();
}
return answers;
}
public static void main(String[] args) {
二叉搜索树中的众数501 二叉搜索树中的众数501 = new 二叉搜索树中的众数501();
二叉搜索树中的众数501.add(1L);
二叉搜索树中的众数501.add(1L);
}
}
解法二:因为该数左孩子一定小于等于根节点,右树一定大于等于根节点,那么中序遍历肯定是有序数列,那么中序遍历时判断连续相等的最大节点数即可
public class 二叉搜索树中的众数501 {
int maxNum, count;
long last;
Set<Long> maxVal = new HashSet<>();
public void dfs(TreeNode root){
if(root == null){
return;
}
dfs(root.left);
findMax(root.val);
last = root.val;
dfs(root.right);
}
private void findMax(long val) {
if (maxNum == 0 || val == last){
count++;
}else {
count = 1;
}
if(count > maxNum){
maxNum = count;
maxVal.clear();
maxVal.add(val);
}else if(count == maxNum){
maxVal.add(val);
}
}
public int[] findMode(TreeNode root) {
dfs(root);
int[] answers = new int[maxVal.size()];
int i = 0;
for(Long val : maxVal){
answers[i++] = val.intValue();
}
return answers;
}
public static void main(String[] args) {
二叉搜索树中的众数501 二叉搜索树中的众数501 = new 二叉搜索树中的众数501();
InputUtils.buildMiddle();
二叉搜索树中的众数501.findMode(InputUtils.head);
}
}