算法训练营Day19

news2024/9/24 5:31:00

#Java #二叉树 #双指针

开源学习资料

Feeling and experiences:

二叉搜索树的最小绝对差:力扣题目链接

给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值

差值是一个正数,其数值等于两值之差的绝对值。

之前递归搜索树写多了,导致首先想到的方法 是把每个节点与左右子树值的差返回给上一级作比较。

但是该题目更好的做法是用中序遍历:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int minNode; //记录答案
    int pre; //用来记录前一个节点
    public int getMinimumDifference(TreeNode root) {
    //初始化最大值
    minNode = Integer.MAX_VALUE;
    //初始化为-1;
    pre = -1;
    dfs(root);
    return minNode;
    }

    public void dfs(TreeNode node){
        if(node == null){
            return;
        }
        //利用中序遍历
        //先遍历左子树
        dfs(node.left);
        //用pre记录前一个节点的值
        if(pre == -1){
            pre = node.val;
        }else{
            minNode = Math.min(minNode , node.val - pre);
            pre = node.val;
        }
        //遍历右子树
        dfs(node.right);
    }
}

整体思路很简单:就是一个pre指针记录上一个节点的值,与当前值进行相减之后,与minNode中存储的结果作比较(minNode中肯定存放的是更小的值),这样可以更新其结果,遍历完得到最终的结果。

图解如下:

用栈模拟,迭代法:

class Solution {
    public int getMinimumDifference(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode pre = null;
        int result = Integer.MAX_VALUE;

        if(root != null)
            stack.add(root);
        while(!stack.isEmpty()){
            TreeNode curr = stack.peek();
            if(curr != null){
                stack.pop();
                if(curr.right != null)
                    stack.add(curr.right);
                stack.add(curr);
                stack.add(null);
                if(curr.left != null)
                    stack.add(curr.left);
            }else{
                stack.pop();
                TreeNode temp = stack.pop();
                if(pre != null)
                    result = Math.min(result, temp.val - pre.val);
                pre = temp;
            }
        }
        return result;
    }
}

 

 

二叉搜索树中的众数:力扣题目链接

给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。

如果树中有不止一个众数,可以按 任意顺序 返回。

假定 BST 满足如下定义:

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

我根据上一个题的思路写了一个解法:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    //该树是一个二叉搜索树
    List<Integer> list = new ArrayList<>();
    int pre = -1;
    int preCount = 0;
    int maxCount = 0;
    public int[] findMode(TreeNode root) {
    dfs(root);
    addMore(pre,preCount);

    int [] res = new int[list.size()];
   

    for(int i =0;i<list.size();i++){
        res[i] = list.get(i);
    }
    return res;
    }
    public void dfs(TreeNode node){
        if(node == null){
            return;
        }
        dfs(node.left);
        if(pre == -1 || pre != node.val){
           addMore(pre,preCount);
           pre = node.val;
           preCount = 1;
        }else{
            preCount++;
        }
        dfs(node.right);
    }

    public void addMore(int value,int count){
        if(count > maxCount){
            maxCount = count;
            list.clear();
            if(value != -1)
                list.add(value);
            }else if(count == maxCount && value != -1){
                list.add(value);
            }
        }
    
}

不过,这段代码不能处理以下测试:

 

 更改后的代码:

class Solution {
    ArrayList<Integer> resList;
    int maxCount;
    int count;
    TreeNode pre;

    public int[] findMode(TreeNode root) {
        resList = new ArrayList<>();
        maxCount = 0;
        count = 0;
        pre = null;
        findMode1(root);
        int[] res = new int[resList.size()];
        for (int i = 0; i < resList.size(); i++) {
            res[i] = resList.get(i);
        }
        return res;
    }

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

        int rootValue = root.val;
        // 计数
        if (pre == null || rootValue != pre.val) {
            count = 1;
        } else {
            count++;
        }
        // 更新结果以及maxCount
        if (count > maxCount) {
            resList.clear();
            resList.add(rootValue);
            maxCount = count;
        } else if (count == maxCount) {
            resList.add(rootValue);
        }
        pre = root;

        findMode1(root.right);
    }
}

 

 二叉树的最近公共祖先:力扣题目链接

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

用后序遍历,从后往前找!

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) { // 递归结束条件
            return root;
        }

        // 后序遍历
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);

        if(left == null && right == null) { // 若未找到节点 p 或 q
            return null;
        }else if(left == null && right != null) { // 若找到一个节点
            return right;
        }else if(left != null && right == null) { // 若找到一个节点
            return left;
        }else { // 若找到两个节点
            return root;
        }
    }
}

莫思身外无穷事,

且尽生前有限杯。

Fighting!

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1324680.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Matlab实现声音信号处理

利用Matlab软件对声音信号进行读取、放音、存储 先去下载一个声音文件&#xff1b;使用这个代码即可 clear; clc; [y, Fs] audioread(xxx.wav); plot(y); y y(:, 1); spectrogram(y); sound(y, Fs); % player audioplayer(y, Fs);y1 diff(y(:, 1)); subplot(2, 1, 1); pl…

107基于matlab的模糊推理系统(ANFIS)的时间序列预测

基于matlab的模糊推理系统&#xff08;ANFIS&#xff09;的时间序列预测&#xff0c;输出训练集、测试集和预测数据结果&#xff0c;数据可更换自己的&#xff0c;程序已调通&#xff0c;可直接运行。 107 时间序列预测模糊推理系统 (xiaohongshu.com)

uniapp的editor组件在H5上无法点击的问题处理

uniapp开发的移动端H5和小程序&#xff0c;富文本框输入框使用了editor的组件 在小程序端是运行正常的&#xff0c;但是在H5端出现了无法点击的情况&#xff0c;是好时坏 原因是H5端依赖远端的quill.min.js组件&#xff0c;该远端的组件偶尔会出现访问的情况 文档上写的比较清…

[AutoSar]基础部分 RTE 02 S/R Port 显式/隐式

目录 关键词平台说明一、显式&#xff08;Explicit&#xff09;和隐式&#xff08;Implicit&#xff09;1.1 显式模式1.1.1code 二、隐式模式2.1 code 三、区别 关键词 嵌入式、C语言、autosar、EcuM、Rte 平台说明 项目ValueOSautosar OSautosar厂商vector芯片厂商TI编程语…

若依(ruoyi)管理系统标题和logo修改

1、网页上的logo 2、页面中的logo 进入ruoyi-ui --> src --> assets --> logo --> logo.png&#xff0c;把这个图片换成你自己的logo 3、网页标题 进入ruoyi-ui --> src --> layout --> components --> Sidebar --> Logo.vue&#xff0c;将里面的…

轻量封装WebGPU渲染系统示例<50>- Json数据描述材质等3D渲染场景信息

本示例中的3d渲染场景由Json数据来描述。 包含3个主要部分: 1. Json描述渲染器的基本信息。 2. Json描述渲染场景的环境信息,包括全局的灯光、阴影、雾等。 3. Json描述构成场景的各个可选人实体&#xff0c;包括几何信息、transform、材质、渲染状态等。 当前示例源码git…

系列二十八、如何在Oracle官网下载JDK的api文档

一、官网下载JDK的api文档 1.1、官网地址 https://www.oracle.com/java/technologies/javase-jdk21-doc-downloads.html 1.2、我分享的api.chm 链接&#xff1a;https://pan.baidu.com/s/1Bf55Fz-eMTErmQDtZZcewQ?pwdyyds 提取码&#xff1a;yyds 1.3、参考 https://ww…

VSCode调试Vue项目

前言 代码在某个平台运行时&#xff0c;会将运行时的状态通过某种方式暴露出来。这些状态信息可以通过某种方式传递给开发工具&#xff0c;以便进行UI的展示和交互。这样的交互可以辅助开发者排查问题、梳理流程&#xff0c;并更好地了解代码的运行状态。这就是我们通常所说的调…

Python爬虫---解析---xpath

1.1 安装xpath&#xff1a; 点击安装Xpath 1.2 将安装好的程序解压&#xff0c;打开浏览器&#xff0c;找到程序扩展&#xff0c;把解压好的程序托进来&#xff0c;如下图所示&#xff1a; 1.3 设置快捷键&#xff1a;打开/关闭xpath 1.4 成功后的图例&#xff1a;按刚刚设…

web前端游戏项目-雷霆战机飞机大战游戏【附源码】

文章目录 一&#xff1a;雷霆战机HTML源码&#xff1a;JS文件&#xff1a;&#xff08;1&#xff09;function.js&#xff08;2&#xff09;impact.js&#xff08;3&#xff09;move.1.1.js&#xff08;4&#xff09;script.js 二&#xff1a;飞机大战HTML源码&#xff1a;CSS源…

文件操作入门指南

目录 一、为什么使用文件 二、什么是文件 2.1 程序文件 2.2 数据文件 2.3 文件名 三、文件的打开和关闭 3.1 文件指针 3.2 文件的打开和关闭 四、文件的顺序读写 ​编辑 &#x1f33b;深入理解 “流”&#xff1a; &#x1f342;文件的顺序读写函数介绍&#xff1a; …

池化层(pooling)

目录 一、池化层 1、最大池化层 2、平均池化层 3、总结 二、代码实现 1、最大池化与平均池化 2、填充和步幅(padding和strides) 3、多个通道 4、总结 一、池化层 1、最大池化层 2、平均池化层 3、总结 池化层返回窗口中最大或平均值环节卷积层对位置的敏感性同样有窗口…

【SpringBoot快速入门】(2)SpringBoot的配置文件与配置方式详细讲解

之前我们已经学习的Spring、SpringMVC、Mabatis、Maven&#xff0c;详细讲解了Spring、SpringMVC、Mabatis整合SSM的方案和案例&#xff0c;上一节我们学习了SpringBoot的开发步骤、工程构建方法以及工程的快速启动&#xff0c;从这一节开始&#xff0c;我们开始学习SpringBoot…

【JAVA】重力反弹,反弹高次一次比一次低

本来是想实现泡泡屏保(javascript实现漂亮的气泡碰撞效果(Chrome浏览器下更佳) 下载-脚本之家)的&#xff0c;还未实现 import javax.swing.*; import java.awt.*; import java.util.LinkedList; import java.util.Random;class Bubble {public static Image image;public int…

Zoho Mail:1600万企业用户的信赖之选

Zoho Mail和Workplace在线办公套件一起&#xff0c;已经成长为一个集邮箱、即时通讯、生产力工具于一身的非常全面的强大平台。经过数十年持续深入的研发投入&#xff0c;我们的产品可以很好地服务大型企业。 这是Zoho创始人斯瑞达•温布在Zoho Mail15周年之际发布的感想。 过去…

C语言——内存函数的使用与模拟实现

大家好&#xff0c;我是残念&#xff0c;希望在你看完之后&#xff0c;能对你有所帮助&#xff0c;有什么不足请指正&#xff01;共同学习交流 本文由&#xff1a;残念ing 原创CSDN首发&#xff0c;如需要转载请通知 个人主页&#xff1a;残念ing-CSDN博客&#xff0c;欢迎各位…

Linux:控制用户的密码—(有效期下次登录必须修改密码)

设置密码有效期 办法1 chage -M 天数 用户名 passwd -x 天数 用户名 可以看到a1 设置了10天 a2 100天 a3没有被设置就是99999 办法2 编辑/etc/login.defs vim /etc/login.defs 设置今后添加用户时的默认密码有效期&#xff0c;也就是新建的用户密码有效期 修改里面的 PASS_…

九.数据处理之增删改

数据处理之增删改 1.插入数据1.1实际问题1.2方式1&#xff1a;VALUES的方式添加1.3方式2&#xff1a;将查询结果插入到表中 2.更新数据3.删除数据4.MySQL8新特性&#xff1a;计算列5.综合案例 1.插入数据 1.1实际问题 解决方式&#xff1a;使用INSERT语句向表中插入数据 1.2方…

LEFT JOIN

通過中間表説明 biz_email_sent table1 biz_email table2 biz_email_sent_address 中間表 LEFT JOIN 是 JOIN 左邊的記錄(biz_email_sent id52)全部查出&#xff0c;比如52 的記錄全部查出。 即使中間表se.sa_email_id 在 table2中找不到&#xff0c…

打破枯燥工作日,用Python统计键盘和鼠标点击次数,钉钉告诉你今天摸鱼了多少次!

1 前言 是否曾想过&#xff0c;在一天的工作中&#xff0c;你到底点击了键盘多少次&#xff0c;或者鼠标点击了多少下&#xff1f; 是否好奇每天工作的时候&#xff0c;自己究竟有多努力&#xff1f; 本文将带你使用 Python&#xff0c;利用 pynput 监听键盘和鼠标事件&…