zoukankan      html  css  js  c++  java
  • 算法与数据结构-树-简单-二叉搜索树中的众数

    二叉搜索树中的众数

    题目

    leetcode原题:501. 二叉搜索树中的众数

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

    假定 BST 有如下定义:

    • 结点左子树中所含结点的值小于等于当前结点的值
    • 结点右子树中所含结点的值大于等于当前结点的值
    • 左子树和右子树都是二叉搜索树

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

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

    分析

    树的题目要求众数,那么求众数的基础就是遍历树+保存中间值,最后返回众数,乍一看蛮简单。但进阶中的需求提到,尽量不使用额外的空间,意思是不使用map能不能做到?

    一般来说,解题分为两种思路:

    • 蛮力遍历,保存中间值,通过保存下来的中间值计算输出需要的结果。
    • 通过某种方式使得数据有序,在有序的基础上去思考如何不使用额外空间,仅使用O(1)的空间复杂度来解决问题。

    首先思考如何有序遍历

    题目有一个特殊的条件,这个树为二叉搜索树,二叉搜索树本身是一定程度有序的,左子树一定小于等于根节点,右子树一定大于等于根节点,那么如何通过遍历让节点有序输出呢?考虑树的三种遍历方式,中序遍历可以实现这个需求!

    然后思考如何使用O(1)的空间复杂度来求得众数。

    思考到这里,题目就转变为了如果给你一个有序数组,如何使用O(1)空间复杂度求得众数。

    考虑一个具体问题:[-1,0,1,1,2,3]

    遍历到-1时,众数结果数组为[-1],maxCount=1,依次类推,遍历到第一个1之后,众数数组为[-1,0,1],maxCount依旧为1,接着遍历第二个1,这时发现1的个数为2,大于maxCount,所以需要清空数组,重新把1放进去,并更新maxCount为2,下面的2和3都因为个数小于maxCount不会被加入众数数组中,至此遍历结束。

    分析上面的思路,我们需要三个int变量,一个记录了上次遍历数据,一个记录了上次数据的连续个数,另外一个记录了maxCount。

    这样大框架就出来了!

    总结一下这部分:

    • 中序遍历使得从小到大有序
    • 利用三个int变量记录中间结果,达到O(1)的时间复杂度

    代码

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
    
        private List<Integer> resultList = new ArrayList<>();
        private int lastNumber;
        private int lastCount;
        private int maxCount;
        
        public int[] findMode(TreeNode root) {
            middleTree(root);
    
            int[] result = new int[resultList.size()];
            for(int i = 0;i<=resultList.size()-1;i++){
                result[i] = resultList.get(i);
            }
            return result;
        }
    
        private void middleTree(TreeNode root){
            if(root == null){
                return;
            }
            middleTree(root.left);
            updateList(root.val);
            middleTree(root.right);
        }
    
        private void updateList(int val){
            if(resultList.size() == 0){
                lastNumber = val;
                lastCount = 1;
                maxCount = 1;
                resultList.add(val);
            }else{
               if(val == lastNumber){
                   lastCount++;
               }else{
                   lastNumber = val;
                   lastCount = 1;
               }
    
               if(lastCount > maxCount){
                  //清空原来list
                  resultList.clear();
                  //加入
                  resultList.add(val);
                  //更新maxCount 为 lastCount
                  maxCount = lastCount;
               }else if(lastCount == maxCount){
                   //加入
                   resultList.add(val);
               }else{
                   //不加入
               }
            }
        }
    }
    
  • 相关阅读:
    奶萨的团队框架(Grid)个人设置技巧以及使用方法
    巫妖王之怒:3.35暗牧输出手法入门指引
    WLK3.3.5治疗怎么玩:治疗职业心得汇总
    WLK奥术fs怎么打高DPS
    战斗贼入门级输出循环
    3.35国服法师DPS提升指引 奥与火的双重奏
    3.35奶萨新手无聊看看帖
    邪冰双手(鲜血领域)——新手推荐,AOE和移动战都不错
    WLK 防骑T
    WLK防骑拉怪手法(要有序排列再给我答案)
  • 原文地址:https://www.cnblogs.com/ging/p/14262647.html
Copyright © 2011-2022 走看看