二叉搜索树中的众数

    欢迎大家访问handsomecui的博客,转载请注明地址https://www.cnblogs.com/handsomecui,欢迎加入技术群讨论:778757421

来源:https://leetcode-cn.com/problems/find-mode-in-binary-search-tree

给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。

假定 BST 有如下定义:

结点左子树中所含结点的值小于等于当前结点的值

结点右子树中所含结点的值大于等于当前结点的值

左子树和右子树都是二叉搜索树

例如:

给定 BST [1,null,2,2],

 

 返回[2].

提示:如果众数超过1个,不需考虑输出顺序

进阶:你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)

 

题解:简单的思路是hash解法,根据数值绝对值取模,每次插入查一下存不存在,存在直接加,不存在插入hash节点,这样解需要额外的空间。

那么如何不使用额外的空间?

解法一(hash):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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);
    }
 
} 

解法二:因为该数左孩子一定小于等于根节点,右树一定大于等于根节点,那么中序遍历肯定是有序数列,那么中序遍历时判断连续相等的最大节点数即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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);
    }
 
}

  

posted @   handsomecui  阅读(202)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
历史上的今天:
2015-09-27 组合数(dfs)
2015-09-27 吝啬的国度(dfs+vector)
2015-09-27 Cube Stacking(并差集深度+结点个数)
点击右上角即可分享
微信分享提示