代码随想录算法训练营(JAVA)| 第六章 二叉树part07

news/2024/7/20 20:55:40 标签: 算法, java, leetcode, 数据结构, 深度优先

      今日任务 

力扣 530. 二叉搜索树的最小绝对差,501. 二叉搜索树中的众数

题目 :530. 二叉搜索树的最小绝对差

思路

注意是二叉搜索树,二叉搜索树可是有序的。

遇到在二叉搜索树上求什么最值啊,差值之类的,就把它想成在一个有序数组上求最值,求差值

那么二叉搜索树采用中序遍历,其实就是一个有序数组。

在一个有序数组上求两个数最小差值,这是不是就是一道送分题了。

最直观的想法,就是把二叉搜索树转换成有序数组,然后遍历一遍数组,就统计出来最小差值了。

递归

那么二叉搜索树采用中序遍历,其实就是一个有序数组。

在一个有序数组上求两个数最小差值,这是不是就是一道送分题了。

最直观的想法,就是把二叉搜索树转换成有序数组,然后遍历一遍数组,就统计出来最小差值了。

如何转换成有序数组?----需要一个pre节点

具体如何实现请看代码  

题解

java">class Solution {
    TreeNode pre;// 记录上一个遍历的结点
    int result = Integer.MAX_VALUE;
    public int getMinimumDifference(TreeNode root) {
       if(root==null)return 0;
       traversal(root);
       return result;
    }
    public void traversal(TreeNode root){
        if(root==null)return;
        //左
        traversal(root.left);
        //中
        if(pre!=null){
            result = Math.min(result,root.val-pre.val);
        }
        pre = root;
        //右
        traversal(root.right);
    }
}

总结

遇到在二叉搜索树上求什么最值,求差值之类的,都要思考一下二叉搜索树可是有序的,要利用好这一特点。

同时要学会在递归遍历的过程中如何记录前后两个指针,这也是一个小技巧,学会了还是很受用的。

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

思路

  哈希表呗,先都存进去在找最大的

是二叉搜索树

既然是搜索树,它中序遍历就是有序的


寸止!先让我们来学习一下

普通二叉树是如何寻找众数:  总共需要遍历二遍
  1. 这个树都遍历了,用map统计频率
  2. 把统计的出来的出现频率(即map中的value)排个序
  3. 取前面高频的元素
二叉搜索树:   总共只需要遍历一遍

把握搜索树,中序遍历就是有序的的特性。

图中实线为遍历后的结果

中序遍历-伪代码

java">void searchBST(TreeNode cur) {
    if (cur == NULL) return ;
    searchBST(cur.left);       // 左
    (处理节点)                // 中
    searchBST(cur.right);      // 右
    return ;
}
  1. 利用性质中序遍历转换成升序排列 
  2. 遍历有序数组的元素出现频率 一边遍历一边比较 动态寻找最大值

而在本题中“最大频率的数可能不止有一个”,因此  需要动态调整最大频率和最大频率值。

统计频率-伪代码

java">if (pre == NULL) { // 第一个节点
    count = 1; // 频率为1
} else if (pre.val == cur.val) { // 与前一个节点数值相同
    count++;
} else { // 与前一个节点数值不同
    count = 1;
}
pre = cur; // 更新上一个节点

查找最值-伪代码

频率count 大于 maxCount的时候,不仅要更新maxCount,而且要清空结果集(以下代码为result数组),因为结果集之前的元素都失效了。

java">        if (count > maxConut)
        {
            resList.add(rootValue); // 更新最大频率
            resList.clear();  // 很关键的一步,不要忘记清空result,之前result里的元素都失效了

            maxConut = count;
        } else if (count == maxConut) {
            resList.add(rootValue);
        }

题解

普通二叉树实现

在这段代码中:

  1. 我们定义了一个countMap来记录每个数值出现的次数。
  2. traverse方法用于递归遍历整棵树,同时更新countMap
  3. 在遍历结束后,我们遍历countMap来找到出现次数等于maxCount的所有数值,这些就是众数。
  4. 最后,我们把众数列表转换成数组并返回。

这种方法不依赖于二叉搜索树的性质,适用于任何二叉树。不过,它的空间复杂度相对较高,因为需要存储树中所有不同值的计数。

java">import java.util.*;


class Solution {
    private Map<Integer, Integer> countMap = new HashMap<>();
    private int maxCount = 0;

    public int[] findMode(TreeNode root) {
        traverse(root);

        List<Integer> modes = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : countMap.entrySet()) {
            if (entry.getValue() == maxCount) {
                modes.add(entry.getKey());
            }
        }

        int[] result = new int[modes.size()];
        for (int i = 0; i < modes.size(); i++) {
            result[i] = modes.get(i);
        }
        return result;
    }

    private void traverse(TreeNode node) {
        if (node == null) return;
        countMap.put(node.val, countMap.getOrDefault(node.val, 0) + 1);
        int count = countMap.get(node.val);
        maxCount = Math.max(maxCount, count);

        traverse(node.left);
        traverse(node.right);
    }
}
二叉搜索树
中序遍历-不使用额外空间,利用二叉搜索树特性
java">class Solution {
    ArrayList<Integer> resList = new ArrayList<>();
    int maxConut, count;
    TreeNode pre;
    public int[] findMode(TreeNode root) {
        pre = null;
        func(root);
        int[] res = new int[resList.size()];
        for (int i = 0; i < resList.size(); i++ ) 
        {
            res[i] = resList.get(i);
        }
        return res;
    }

    public void func(TreeNode root) {
        if (root == null) return;
        func(root.left);

        int rootValue = root.val;
        if (pre == null || rootValue != pre.val)
        {
            // 重置值
            count = 1;
        } else
        {
            count++;
        }

        if (count > maxConut)
        {
            resList.clear();
            resList.add(rootValue);
            maxConut = count;
        } else if (count == maxConut) {
            resList.add(rootValue);
        }
        pre = root;

        func(root.right);
    }
}
迭代法 
java">class Solution {
    public int[] findMode(TreeNode root) {
        TreeNode pre = null;
        Stack<TreeNode> stack = new Stack<>();
        List<Integer> result = new ArrayList<>();
        int maxCount = 0, count = 0;
        TreeNode cur = root;
        while (cur != null || !stack.isEmpty())
        {
            if (cur != null)
            {
                stack.push(cur);
                cur = cur.left;
            } else 
            {
                cur = stack.pop();

                if (pre == null || cur.val != pre.val)
                {
                    count = 1;
                } else 
                {
                    count++;
                }

                if (count > maxCount)
                {
                    maxCount = count;
                    result.clear();
                    result.add(cur.val);
                } else if (count == maxCount)
                {
                    result.add(cur.val);
                }

                pre = cur;
                cur = cur.right;
            }
        }
        return result.stream().mapToInt(Integer::intValue).toArray();
    }
}


http://www.niftyadmin.cn/n/5435037.html

相关文章

用python如何实现智能合约?如何使用remix编写solidity智能合约并部署上链

目录 用python如何实现智能合约? 直接展示下成功界面 下面分步骤说: remix代码 python链接remix代码

Python之Web开发中级教程----ubuntu中下载安装Postman

Python之Web开发中级教程----ubuntu中下载安装Postman PostMan 是一款功能强大的网页调试与发送网页 HTTP 请求的 Chrome 插件&#xff0c;可以直接去对我们写出来的路由和视图函数进行调试&#xff0c;作为后端程序员是必须要知道的一个工具。 查看ubuntu系统中是否已经安装了…

TypeScript快速入门过基础语法

TypeScript快速入门过基础语法 官方文档&#xff1a;[基础类型 TypeScript中文网 TypeScript——JavaScript的超集 (tslang.cn)](https://www.tslang.cn/docs/handbook/namespaces.html) 1、模版字符串 let name: string Gene; let age: number 37; let sentence: strin…

KubeSphere集群安装-nfs分布式文件共享-对接Harbor-对接阿里云镜像仓库-遇到踩坑记录

KubeSphere安装和使用集群版 官网:https://www.kubesphere.io/zh/ 使用 KubeKey 内置 HAproxy 创建高可用集群:https://www.kubesphere.io/zh/docs/v3.3/installing-on-linux/high-availability-configurations/internal-ha-configuration/ 特别注意 安装前注意必须把当前使…

【AI】Ubuntu系统深度学习框架的神经网络图绘制

一、Graphviz 在Ubuntu上安装Graphviz&#xff0c;可以使用命令行工具apt进行安装。 安装Graphviz的步骤相对简单。打开终端&#xff0c;输入以下命令更新软件包列表&#xff1a;sudo apt update。之后&#xff0c;使用命令sudo apt install graphviz来安装Graphviz软件包。为…

【洛谷 P9242】[蓝桥杯 2023 省 B] 接龙数列 题解(线性DP+二维数组)

[蓝桥杯 2023 省 B] 接龙数列 题目描述 对于一个长度为 K K K 的整数数列&#xff1a; A 1 , A 2 , … , A K A_{1},A_{2},\ldots,A_{K} A1​,A2​,…,AK​&#xff0c;我们称之为接龙数列当且仅当 A i A_{i} Ai​ 的首位数字恰好等于 A i − 1 A_{i-1} Ai−1​ 的末位数字…

论文阅读_参数微调_P-tuning_v2

1 P-Tuning PLAINTEXT 1 2 3 4 5 6 7英文名称: GPT Understands, Too 中文名称: GPT也懂 链接: https://arxiv.org/abs/2103.10385 作者: Xiao Liu, Yanan Zheng, Zhengxiao Du, Ming Ding, Yujie Qian, Zhilin Yang, Jie Tang 机构: 清华大学, 麻省理工学院 日期: 2021-03-18…

JVM学习-常量池、运行时常量池以及串池

1.常量池 常量池就是一张表&#xff0c;里面存储了运行所需要的类名、方法名、参数类型、字面量等信息&#xff0c;在JVM中虚拟机指令根据这张表来找到执行程序所需要的信息。当类还没有被加载到JVM中时&#xff0c;常量池就在每个类对应的class文件中&#xff0c;其中每条信息…