【算法系列之二叉树III】leetcode236. 二叉树的最近公共祖先

2023/9/30 18:42:26

617.合并二叉树

力扣题目链接

给你两棵二叉树: root1root2

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。

返回合并后的二叉树。

注意: 合并过程必须从两个树的根节点开始。

输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出:[3,4,5,5,4,null,7]

解决思路

  1. 如果树节点为空,则用另一颗树的节点。

Java实现

class Solution_LC617 {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if (root1 == null) {
            return root2;
        }
        if (root2 == null) {
            return root1;
        }
        int val = root1.val + root2.val;
        TreeNode root = new TreeNode(val);
        root.left = mergeTrees(root1.left, root2.left);
        root.right = mergeTrees(root1.right, root2.right);
        return root;
    }
}

700.二叉搜索树中的搜索

力扣题目地址

给定二叉搜索树(BST)的根节点 root 和一个整数值 val

你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null

输入:root = [4,2,7,1,3], val = 2
输出:[2,1,3]

解决思路

二叉搜索树是一个有序树:

若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
它的左、右子树也分别为二叉搜索树
  1. 当root的值>指定的值,从左子树上尝试获取;否则从右子树上获取
  2. 当root的值>指定的值,左子树上都是比root的值小的,右子树上都是比root的值大的。

Java实现

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if (root == null || root.val == val) {
            return root;
        }
        if (root.val > val) {
            return searchBST(root.left, val);
        } else {
            return searchBST(root.right, val);
        }
    }
}

98.验证二叉搜索树

力扣题目链接

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。
输入:root = [2,1,3]
输出:true

解决思路

  1. 构建新的递归函数,不断更新上限值和下限值。
  2. 中序遍历,不断比较节点
  3. 中序遍历,构成数组比较。

Java实现

递归实现

class Solution {
    public boolean isValidBST(TreeNode root) {

        return validBST(root, Long.MIN_VALUE, Long.MAX_VALUE);

    }

    private boolean validBST(TreeNode root, long lower, long upper) {
        if (root == null) {
            return true;
        }
        if (root.val <= lower || root.val >= upper) return false;
        return validBST(root.left, lower, root.val) && validBST(root.right, root.val, upper);
    }
}

中序遍历,左中右

class Solution_LC98_II {
    public boolean isValidBST(TreeNode root) {

        Stack<TreeNode> stack = new Stack<>();
        long inorder = Long.MIN_VALUE;
        TreeNode cur = root;
        while (!stack.isEmpty() || cur != null) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.pop();
            if (cur.val <= inorder) {
                return false;
            }
            inorder = cur.val;
            cur = cur.right;
        }
        return true;
    }
}

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

力扣题目链接

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

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

输入:root = [4,2,6,1,3]
输出:1

解决思路

  1. 因为要获取最小值,result的初始值设置为最大。
  2. 使用中序遍历。

Java实现

class Solution {
    public int getMinimumDifference(TreeNode root) {
        int res = Integer.MAX_VALUE;
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        TreeNode pre = null;
        while (!stack.isEmpty() || cur != null) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.pop();
            if (pre != null) {
                res = Math.min(cur.val - pre.val, res);
            }
            pre = cur;
            cur = cur.right;
        }
        return res;
    }

}

501.二叉搜索树中的众数

力扣题目链接

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

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

假定 BST 满足如下定义:

  • 结点左子树中所含节点的值 小于等于 当前节点的值
  • 结点右子树中所含节点的值 大于等于 当前节点的值
  • 左子树和右子树都是二叉搜索树
输入:root = [1,null,2,2]
输出:[2]

解题思路

  1. 使用中序遍历,去挨个遍历二叉树上的元素。如果当前元素和前一个元素一致,计数+1。
  2. 使用全局变量,记录当前元素的次数;最大的次数。

Java实现

使用递归的方式

class Solution_LC501 {
    List<Integer> answers = new ArrayList<>();
    int base, count, maxCount;

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

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

    private void dfs(TreeNode cur) {
        if (cur == null) {
            return;
        }
        dfs(cur.left);
        caluate(cur.val);
        dfs(cur.right);
    }

    private void caluate(int val) {
        if (val == base) {
            count++;
        } else {
            count = 1;
            base = val;
        }
        if (count == maxCount) {
            answers.add(val);
        }
        if (count > maxCount) {
            maxCount = count;
            answers.clear();
            answers.add(val);
        }
    }
}

使用中序迭代

class Solution_LC501_II {
    List<Integer> answers = new ArrayList<>();
    int count, maxCount;

    public int[] findMode(TreeNode root) {
        TreeNode cur = root;
        TreeNode pre = null;
        Stack<TreeNode> stack = new Stack<>();
        while (!stack.isEmpty() || cur != null) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.pop();
            if (pre == null) {
                count = 1;
            } else if (pre.val == cur.val) {
                count++;
            } else {
                count = 1;
            }
            if (count == maxCount) {
                answers.add(cur.val);
            }
            if (count > maxCount) {
                maxCount = count;
                answers.clear();
                answers.add(cur.val);
            }

            pre = cur;
            cur = cur.right;
        }
        int[] mode = new int[answers.size()];
        for (int i = 0; i < answers.size(); ++i) {
            mode[i] = answers.get(i);
        }
        return mode;
    }
}

236. 二叉树的最近公共祖先

力扣题目链接

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

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

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。

解题思路

  1. 如果找到一个节点,发现左子树出现结点p,右子树出现节点q,或者 左子树出现结点q,右子树出现节点p,那么该节点就是节点p和q的最近公共祖先。
  2. 在子树上找到p或者q,就可以了。如果p和q分别在两个子树上都可以分别找到,则当前节点是公共祖先。

Java实现

class Solution_LC236 {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) {
            return root;
        }
        //后序遍历
        TreeNode leftNode = lowestCommonAncestor(root.left, p, q);
        TreeNode rightNode = lowestCommonAncestor(root.right, p, q);
        if (leftNode == null && rightNode == null) {
            return null;
        }
        if (leftNode == null) {
            return rightNode;
        }
        if (rightNode == null) {
            return leftNode;
        }
        return root;
    }
}

235. 二叉搜索树的最近公共祖先

力扣题目链接

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

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

例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6 
解释: 节点 2 和节点 8 的最近公共祖先是 6。

解题思路

  1. 公共祖先的节点的值的大小必须大于等于左节点,小于等于右节点。如果当前节点的值比p和q节点的值都要大,可以在左子树上继续寻找,左子树上都是比当前节点小的数据。如果当前节点的值比p和q的节点都要小的话,在右子树上寻找。

Java实现

递归方式

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root.val > p.val && root.val > q.val) {
            return lowestCommonAncestor(root.left, p, q);
        }
        if (root.val < p.val && root.val < q.val) {
            return lowestCommonAncestor(root.right, p, q);
        }
        return root;
    }
}

非递归方式

public class Solution_LC235_II {

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        while (true) {
            if (root.val > p.val && root.val > q.val) {
                root = root.left;
            } else if (root.val < p.val && root.val < q.val) {
                root = root.right;
            } else {
                break;
            }
        }
        return root;
    }
}

在这里插入图片描述


http://www.jnnr.cn/a/505800.html

相关文章

脱岗监测预警系统 yolov5

脱岗监测预警系统可以通过pythonyolov5网络模型深度学习算法&#xff0c;脱岗监测预警算法对现场人员岗位进行实时监测&#xff0c;自动识别是否存在脱岗行为&#xff0c;并及时发出警报。Yolo意思是You Only Look Once&#xff0c;它并没有真正的去掉候选区域&#xff0c;而是…

8:00面试,8:03就出来了 ,问的些许变态了吧

这年头&#xff0c;面试没两把刷子&#xff0c;还真不容易 我刚从外包出来&#xff0c;没想到还没多久就死在另一家大厂了 自从加入这家外包公司&#xff0c;每天不是在加班就是在加班的路上&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到3月一纸通知&#xff0…

斩获阿里offer,这份258页面试宝典也太顶了....

测试三年有余&#xff0c;很多新学到的技术不能再项目中得到实践&#xff0c;同时薪资的涨幅很低&#xff0c;于是萌生了跳槽大厂的想法 但大厂不是那么容易进的&#xff0c;前面惨败字节&#xff0c;为此我辛苦准备了两个月&#xff0c;又从小公司开始面试了半个月有余&#…

Maven 介绍,根据 Maven 官方文档整理

这部分内容主要根据 Maven 官方文档整理&#xff0c;做了对应的删减&#xff0c;主要保留比较重要的部分&#xff0c;不涉及实战&#xff0c;主要是一些重要概念的介绍。 Maven 介绍 Maven 官方文档是这样介绍的 Maven 的&#xff1a; Apache Maven is a software project man…

基于AT89C51单片机的6位电子密码锁详细设计

点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87855657?spm=1001.2014.3001.5503 源码获取 目录 1绪论 1 1.1 课题背景 1 1.2 课题设计目标 1 2系统方案论证 2 2.1 主控部分的选择 2 2.2 密码输入方式的选择 2 3 系统总体…

这才叫软件测试工程师,你那最多是混口饭吃罢了....

前些天和大学室友小聚了一下&#xff0c;喝酒喝大发了&#xff0c;谈天谈地谈人生理想&#xff0c;也谈到了我们各自的发展&#xff0c;感触颇多。曾经找工作我迷茫过、徘徊不&#xff0c;毕业那会我屡屡面试失败&#xff0c;处处碰壁&#xff1b;工作两年后我一度想要升职加薪…

【Rust学习】web框架 Axum,提供REST API

cargo-watch:有修改就重启服务器&#xff0c;类似java web的热部署 安装&#xff1a;cargo install cargo-watch 使用&#xff1a;cargo watch -x run 这样每次有修改就会自动重启web服务 vscode插件Thunder Client(类似postman) hello,world 建议用cargo add的方式添加 […

ELECTRA模型简单介绍

目录 一、整体概要 二、生成器 三、判别器 四、模型训练 五、其它改进 一、整体概要 ELECTRA&#xff08;Efficiently Learning an Encoder that Classifies Token Replacements Accurately&#xff09;采用了一种“生成器——判别器”结构&#xff0c;其与生成式对抗网络…

SUSE系统上安装HANA

一:安装SUSE操作系统 1.1 准备安装镜像 SLE-15-SP1-安装程序-DVD-x86_64-GM-DVD1 SLE-15-SP1-软件包-x86_64-GM-DVD1 SAP HANA安装文件 IMDB_SERVER20_032_0-80002031.SAR 1.2 引导系统 1.3 选择要安装的产品 SUSE Linux Enterprise Server for SAP Applications 15 SP…

TDEngine - taosdump的安装与使用实战

taosdump的安装与使用实战 一、taosdump简介二、下载三、安装四、taosdump主要参数五、taosdump数据导出&#xff08;备份&#xff09;六、taosdump数据导入七、不同版本的数据迁移7.1 问题&#xff1a;报错- create database 语句不一致7.2 解决&#xff1a;修改导出的dbs.sql…

application.yml中的配置怎么写

1.问题 application.yml中可以做很多组件的配置,比如redis,mongo, 但是这些的key是什么,value怎么写呢? 2.分析问题 为了搞清楚这个问题,我们需要先了解application.yml中的配置是怎么加载的,以MongoProperties配置加载为例, 在Spring Boot中,可以使用application.y…

Ampere 又放大招,推出自研192 核AmpereOne 系列处理器,已投产

作者 | 伍杏玲 近日&#xff0c;Ampere Computing 发布2023年度战略和产品路线图&#xff0c;并推出全新的AmpereOne系列处理器&#xff0c;拥有多达 192 个单线程 Ampere 核&#xff0c;内核数量为业界最高。这是第一款基于 Ampere 新自研核的产品&#xff0c;由 Ampere 自有…

ISATAP隧道配置与验证

ISATAP隧道配置与验证 【实验目的】 熟悉IPv6ISATAP隧道的概念。 掌握IPv6和IPv4共存的实现方法。 掌握IPv6 ISATAP地址编址规则。 掌握IPv6 ISATAP隧道的配置。 验证配置。 【实验拓扑】 设备参数如下表所示。 设备 接口 IP地址 子网掩码 默认网关 R1 S0/0 192.…

Mysql安装教程(windows)

本文主要讲解如何去安装使用Mysql 一、下载Mysql 1、官网在线下载 MySQL官网&#xff1a;https://www.mysql.com/downloads/ 下载版本&#xff1a;MySQL Installer for Window 2、云盘离线下载 https://pan.baidu.com/s/1dB7kFiwrKpF5W-5XPn2FeQ?pwdrvb9 提取码&#xff1a;…

Rust每日一练(Leetday0020) 最后单词的长度、螺旋矩阵II、排列序列

目录 58. 最后一个单词的长度 Length of Last Word &#x1f31f; 59. 螺旋矩阵 II Spiral Matrix II &#x1f31f;&#x1f31f; 60. 排列序列 Permutation Sequence &#x1f31f;&#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Rust每日…

如何不出国一年内拿到加拿大女王大学金融硕士学位证书?

作为加拿大最好的公立大学之一&#xff0c;QueensUniversity位于安大略省的金斯顿市。最近&#xff0c;它在QS全球大学排名中跻身第209位&#xff0c;同时在加拿大的综合排名中名列第7位。这表明女王大学在学术研究和教育方面都有着出色的表现。Queens University坐落于安大略省…

机器学习——聚类算法详解

1.聚类问题 1&#xff09;聚类问题与核心概念 聚类算法做的事情&#xff0c;就是对无标签的数据&#xff0c;基于数据分布进行分群分组&#xff0c;使得相似的数据尽量落在同一个簇内。 我们先对比区分一下聚类和分类&#xff1a; 聚类是一种无监督学习&#xff0c;而分类是…

NUC980编译错误,arm-linux-gcc: Command not found

报错问题&#xff1a; make: arm-linux-gcc: Command not found /bin/sh: 1: arm-linux-gcc: not found dirname: missing operand 昨天编译的时候&#xff0c;还小甜甜&#xff0c;今天就牛夫人了。啥也没干啊&#xff01; -----------------------------------------------…

男子路遇“纸片鸟”,AI帮忙免惹祸

据报道&#xff0c;近日&#xff0c;河南洛阳一网友在路边偶遇一只“纸片鸟”&#xff0c;小鸟远看像一张纸片&#xff0c;样子十分奇特&#xff0c;而且还死死地盯着自己&#xff0c;像是求救&#xff0c;后来他用手机一查发现是二级保护动物“黄斑苇鳽”&#xff0c;便报警处…

chatgpt赋能python:Python图像处理优化技巧:提高网站SEO效果的必修课程

Python图像处理优化技巧&#xff1a;提高网站SEO效果的必修课程 介绍 在当前数字化时代&#xff0c;网站的SEO优化已经成为了网站营销的重要一环。在优化网站SEO的同时&#xff0c;提升图像处理技巧也成为了重要的一环。Python作为当前最为火热的数据科学语言之一&#xff0c…
最新文章