zoukankan      html  css  js  c++  java
  • 二叉搜索树中的众数

    来源: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);
        }
    
    }
    

      

  • 相关阅读:
    设计模式学习笔记之状态模式
    设计模式学习笔记之观察者模式
    设计模式学习笔记之模板方法模式
    设计模式学习笔记之策略模式
    设计模式学习笔记之装饰者模式
    Comparable和Comparator接口的比较
    Java中关键字continue、break和return的区别
    斐波那契数列-兔子问题
    用Java编程计算猴子吃桃问题
    (转载)Java多线程入门理解
  • 原文地址:https://www.cnblogs.com/handsomecui/p/13740230.html
Copyright © 2011-2022 走看看