算法体系-13 第十三 二叉树的基本算法+二叉树的递归套路

news2024/12/23 22:12:59

一 完全二叉树的判断

1.1 描述

完全二叉树:他每一层都是满的,即使不满也是最后一层不满,最后一层不满也是从左到右变满的;话句话说就是

完全二叉树从根结点到倒数第二层满足完美二叉树,最后一层可以不完全填充,其叶子结点都靠左对齐

1.如果是最后一层,下一轮还有

2.不是从左往右排

判断的时候按层遍历

1、如果某个节点有右孩子,没有左孩子返回false;

2、当越到第一次越到左右孩子不双全的情况下说明这层已经是最后一层既叶子节点,那么接下来的遍历就不能再出现左节点或者有节点有的话就不是;

1.3 代码

public class Code01_IsCBT {

    public static class Node {
        public int value;
        public Node left;
        public Node right;

        public Node(int data) {
            this.value = data;
        }
    }

    public static boolean isCBT1(Node head) {
        if (head == null) {
            return true;
        }
        LinkedList<Node> queue = new LinkedList<>();
        // 是否遇到过左右两个孩子不双全的节点
        boolean leaf = false;
        Node l = null;
        Node r = null;
        queue.add(head);
        while (!queue.isEmpty()) {
            head = queue.poll();
            l = head.left;
            r = head.right;
            if (
            // 如果遇到了不双全的节点之后,又发现当前节点不是叶节点
                (leaf && (l != null || r != null)) 
                || 
                             //如果某个节点有右孩子没有左孩子返回false;
                (l == null && r != null)) {
                return false;
            }
            if (l != null) {
                queue.add(l);
            }
            if (r != null) {
                queue.add(r);
            }
            if (l == null || r == null) {//如果有一个是null了,说明已经是最后一层了,
   //不能再有下一层了,根据这个条件上面判断是否还有下一层,有的话一定就不是
                leaf = true;
            }
        }
        return true;
    }

    public static boolean isCBT2(Node head) {
        if (head == null) {
            return true;
        }
        return process(head).isCBT;
    }

二 平衡二叉树

2.1 描述

它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树

2.2 分析

2.3 代码

public static boolean isBalanced2(Node head) {
        return process(head).isBalanced;
    }
    
    public static class Info{
        public boolean isBalanced;
        public int height;
        
        public Info(boolean i, int h) {
            isBalanced = i;
            height = h;
        }
    }
    
    public static Info process(Node x) {
        if(x == null) {
            return new Info(true, 0);
        }
        Info leftInfo = process(x.left);
        Info rightInfo = process(x.right);
        int height = Math.max(leftInfo.height, rightInfo.height)  + 1;
        boolean isBalanced = true;
        if(!leftInfo.isBalanced) {
            isBalanced = false;
        }
        if(!rightInfo.isBalanced) {
            isBalanced = false;
        }
        if(Math.abs(leftInfo.height - rightInfo.height) > 1) {
            isBalanced = false;
        }
        return new Info(isBalanced, height);
    }
    
    
    

三 搜索二叉树

3.1 描述

若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值;

一颗左子树节点上的值都小于右子树上的值,并且左子树和右子树也要是颗二叉树

3.2 分析

1、 可以通过中序遍历,看是不是升序就可以判断;经典的搜索二叉树是没有重复值的;

2、分析如下,要信息的方法

使用递归收集信息的时候左右节点最大值最小值都要

3.3 代码

public static boolean isBST2(Node head) {
        if (head == null) {
            return true;
        }
        return process(head).isBST;
    }

    public static class Info {
        public boolean isBST;
        public int max;
        public int min;

        public Info(boolean i, int ma, int mi) {
            isBST = i;
            max = ma;
            min = mi;
        }

    }

    public static Info process(Node x) {
        if (x == null) {
            return null;
        }
        Info leftInfo = process(x.left);
        Info rightInfo = process(x.right);
        int max = x.value;
              //找值要到他的子树中去全部找
        if (leftInfo != null) {
            max = Math.max(max, leftInfo.max);
        }
        if (rightInfo != null) {
            max = Math.max(max, rightInfo.max);
        }
        int min = x.value;
        if (leftInfo != null) {
            min = Math.min(min, leftInfo.min);
        }
        if (rightInfo != null) {
            min = Math.min(min, rightInfo.min);
        }
        boolean isBST = true;
        if (leftInfo != null && !leftInfo.isBST) {
            isBST = false;
        }
        if (rightInfo != null && !rightInfo.isBST) {
            isBST = false;
        }
        if (leftInfo != null && leftInfo.max >= x.value) {
            isBST = false;
        }
        if (rightInfo != null && rightInfo.min <= x.value) {
            isBST = false;
        }
        return new Info(isBST, max, min);
    }

四 二叉树的最大距离

4.1 描述

给定一棵二叉树的头节点head,任何两个节点之间都存在距离,

返回整棵二叉树的最大距离

4.2 分析

情况一 和x有关是左右树的最大距离加上本身

情况二 与 x 无关的分别是左右树的最大距离

与x有关的最大距离

最大距离的三种情况

从上面分析:我们需要向子树要的信息就是最大距离和高度

4.3代码

    public static int maxDistance2(Node head) {
        return process(head).maxDistance;
    }

    public static class Info {
        public int maxDistance;
        public int height;

        public Info(int m, int h) {
            maxDistance = m;
            height = h;
        }

    }

    public static Info process(Node x) {
        if (x == null) {
            return new Info(0, 0);
        }
        Info leftInfo = process(x.left);
        Info rightInfo = process(x.right);
        int height = Math.max(leftInfo.height, rightInfo.height) + 1;
        
                int p1 = leftInfo.maxDistance;
        int p2 = rightInfo.maxDistance;
                 //与x有关
        int p3 = leftInfo.height + rightInfo.height + 1;
        int maxDistance = Math.max(Math.max(p1, p2), p3);
        return new Info(maxDistance, height);
    }

五 满二叉树的判断

5.1 描述

如果一棵二叉树的结点要么是叶子结点,要么它有两个子结点,这样的树就是满二叉树;

5.2 分析

5.3 代码

// 第一种方法
    // 收集整棵树的高度h,和节点数n
    // 只有满二叉树满足 : 2 ^ h - 1 == n
    public static boolean isFull1(Node head) {
        if (head == null) {
            return true;
        }
        Info1 all = process1(head);
        return (1 << all.height) - 1 == all.nodes;
    }

    public static class Info1 {
        public int height;
        public int nodes;

        public Info1(int h, int n) {
            height = h;
            nodes = n;
        }
    }

    public static Info1 process1(Node head) {
        if (head == null) {
            return new Info1(0, 0);
        }
        Info1 leftInfo = process1(head.left);
        Info1 rightInfo = process1(head.right);
        int height = Math.max(leftInfo.height, rightInfo.height) + 1;
        int nodes = leftInfo.nodes + rightInfo.nodes + 1;
        return new Info1(height, nodes);
    }

六 一颗二叉树中,整体不是搜索二叉树,可能某个子树是搜索二叉树,子树(某个头节点下所有的子树都要),在整颗二叉树中,有哪一颗子树是搜索二叉树,在所有的搜索二叉子树中找出所有最大的那颗子树有多少个节点并返回

6.1 描述

一颗二叉树中,整体不是搜索二叉树,可能某个子树是搜索二叉树,子树(某个头节点下所有的子树都要),在整颗二叉树中,有那一刻子树是搜索二叉树,在所有的子树中找出所有最大的那颗子树有多少个节点并返回

6.2 分析

信息收集

信息合并 x左和x右就是maxBSTSubSize 左size和右size就是size

BST和size 两个可以合并,当maxBSTSubSize 和size相等的情况就是BST

6.3 代码

package class12;

// 在线测试链接 : https://leetcode.com/problems/largest-bst-subtree
public class Code05_MaxSubBSTSize {

    // 提交时不要提交这个类
    public static class TreeNode {
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int value) {
            val = value;
        }
    }

    // 提交如下的代码,可以直接通过
    public static int largestBSTSubtree(TreeNode head) {
        if (head == null) {
            return 0;
        }
        return process(head).maxBSTSubtreeSize;
    }

    public static class Info {
        public int maxBSTSubtreeSize;
        public int allSize;
        public int max;
        public int min;

        public Info(int m, int a, int ma, int mi) {
            maxBSTSubtreeSize = m;
            allSize = a;
            max = ma;
            min = mi;
        }
    }

    public static Info process(TreeNode x) {
        if (x == null) {
            return null;
        }
        Info leftInfo = process(x.left);
        Info rightInfo = process(x.right);
        int max = x.val;
        int min = x.val;
        int allSize = 1;
        if (leftInfo != null) {
            max = Math.max(leftInfo.max, max);
            min = Math.min(leftInfo.min, min);
            allSize += leftInfo.allSize;
        }
        if (rightInfo != null) {
            max = Math.max(rightInfo.max, max);
            min = Math.min(rightInfo.min, min);
            allSize += rightInfo.allSize;
        }
               //不以x为头的情况
        int p1 = -1;
        if (leftInfo != null) {
            p1 = leftInfo.maxBSTSubtreeSize;
        }
        int p2 = -1;
        if (rightInfo != null) {
            p2 = rightInfo.maxBSTSubtreeSize;
        }
               //以x为头的情况
        int p3 = -1;
        boolean leftBST = leftInfo == null ? true : (leftInfo.maxBSTSubtreeSize == leftInfo.allSize);
        boolean rightBST = rightInfo == null ? true : (rightInfo.maxBSTSubtreeSize == rightInfo.allSize);
        if (leftBST && rightBST) {
            boolean leftMaxLessX = leftInfo == null ? true : (leftInfo.max < x.val);
            boolean rightMinMoreX = rightInfo == null ? true : (x.val < rightInfo.min);
            if (leftMaxLessX && rightMinMoreX) {
                int leftSize = leftInfo == null ? 0 : leftInfo.allSize;
                int rightSize = rightInfo == null ? 0 : rightInfo.allSize;
                p3 = leftSize + rightSize + 1;
            }
        }
        return new Info(Math.max(p1, Math.max(p2, p3)), allSize, max, min);
    }

}

七 本节总结

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

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

相关文章

Elasticsearch数据存储优化方案

优化Elasticsearch数据存储有助于提升系统性能、降低成本、提高数据查询效率以及增强系统的稳定性和可靠性。通常我们再优化Elasticsearch数据存储会遇到一些问题&#xff0c;导致项目卡壳。以下是优化Elasticsearch数据存储的一些重要作用&#xff1a; 1、问题背景 在某些场景…

我的春招求职面经

智能指针在面试时经常被问到&#xff0c;最近自己也在写&#xff0c;有一点思考&#xff0c;于是找到了这样一个题目&#xff0c;可以看看&#xff0c;上面这个代码有什么问题&#xff1f;留言区说出你的答案吧&#xff01; 最后分享一下之前的实习->春招->秋招等文章汇总…

地质灾害在线监测,精准预警智能化

自然灾害无情且威力巨大,对人类生命财产安全造成严重威胁。地质灾害作为重要的自然灾害类型之一,给人类社会带来了沉重的经济损失和生命威胁。及时掌握地质灾害信息,提高预警能力和监测水平,是保障人民群众生命财产安全的当务之急。&#xff08;key-iot.com.cn/18703.html&…

Juniper SRX 防火墙基础上网配置

简介 基于PNET-LAB模拟器&#xff0c;使用 vSRX-NG 23.4R1.9 镜像进行实验。 博客&#xff1a;https://songxwn.com/Juniper-SRX-snat/ 实验需求 配置WAN口 LAN口&#xff0c;实现基础的上网功能。配置NAT、DHCP。 ISP 路由器使用Cisco IOS模拟&#xff0c;与SRX对接口配置…

docker镜像安装空间不足no space left on device

报错&#xff1a;Error processing tar file(exit status 1): open /usr/local/lib/libmkl_tbb_thread.so.1: no space left on device 原先docker模型保存位置&#xff1a; docker info -f ‘{{ .DockerRootDir}}’ docker 高点版本&#xff0c;这里26.0 解决参考&#xf…

力扣---零钱兑换---动态规划

思路&#xff1a; 这是一道典型的动态规划问题&#xff08;希望下次不用提示&#xff0c;能直接认出来&#xff09;&#xff1a;我将g[i]定义为总金币为i所需的最少硬币个数。所以递推公式可以表示为&#xff1a;g[i]min(g[i-1],g[i-2],g[i-5])1&#xff0c;也就是g[i]min(g[i-…

demo版多人聊天系统

目录 ​编辑 一&#xff0c;引入 二&#xff0c;在Server端修改的代码 1&#xff0c;保存用户信息功能实现 2&#xff0c;拼接消息 3&#xff0c;广播消息 三&#xff0c; Client端要修改的代码 四&#xff0c;效果演示 一&#xff0c;引入 在上一篇文章udp网络服务器中&a…

Java-Java基础学习(4)-多线程(2)

3.7. Lambda表达式 为什么要使用lambda表达式 避免匿名内部类定义过多&#xff1b;可以让代码看起来更简洁&#xff1b;去掉一堆没有意义的代码&#xff0c;只留下核心逻辑 属于函数式编程的概念&#xff0c;格式 (params) -> expression [表达式](params) -> statement…

山东省大数据局副局长禹金涛一行莅临聚合数据走访调研

3月19日&#xff0c;山东省大数据局党组成员、副局长禹金涛莅临聚合数据展开考察调研。山东省大数据局数据应用管理与安全处处长杨峰&#xff0c;副处长都海明参加调研&#xff0c;苏州市大数据局副局长汤晶陪同。聚合数据董事长左磊等人接待来访。 调研组一行参观了聚合数据展…

安装OneNote for Win10 | Win10/Win11

前言 PC端的OneNote分为2个版本&#xff0c;分别是Microsoft Store版本和Office版本&#xff0c;Microsoft Store版本即为OneNote for Win10&#xff0c;此版的OneNote有最近笔记功能&#xff0c;但检索功能不如Office版本&#xff0c;个人认为2个版本各有优劣。 但OneNote f…

详细剖析多线程(更新中...)

文章目录 前言一、认识线程1.1线程概念1.2为什么要有线程1.3线程和进程的区别&#xff08;经典面试题&#xff09; 二、创建线程2.1继承 Thread 类,重写run2.2实现 Runnable 接口,重写run2.3继承 Thread 类,重写run&#xff0c;匿名内部类2.4实现 Runnable 接口,重写run&#x…

WEB 表单练习题

任务如图&#xff1a; <html><head><meta charest"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head><body><table width"…

解决nginx报错nginx: [emerg] unknown log format main in 的方法

目录 一、故障描述1&#xff1a; 重启nginx是出现了如下错误 解决办法 二、故障描述2&#xff1a; 解决办法&#xff1a; 三、nginx介绍​ 四、nginx原理 五、nginx.conf配置文件 六、nginx负载均衡 七、正向代理、反向代理 一、故障描述1&#xff1a; 在添加Nginx的…

【WEEK4】 【DAY3】整合SSM框架之功能实现—修改、删除数据【中文版】

2024.3.20 Wednesday 接上文【WEEK4】 【DAY2】整合SSM框架之功能实现—总览、添加数据【中文版】 目录 7.6.修改功能7.6.1.修改BookController.java7.6.2.修改allBook.jsp7.6.3.新建updateBook.jsp7.6.4.修改MyBatis-config.xml7.6.5.运行 7.7.删除功能7.7.1.修改BookContro…

网络原理(4)——TCP协议的特性

目录 一、滑动窗口 1、ack丢了 2、数据丢了 二、流量控制&#xff08;流控&#xff09; 三、拥塞控制 拥塞窗口动态变化的规则 四、延时应答 五、捎带应答 六、面向字节流 七、异常情况 &#xff08;1&#xff09;进程崩溃了 &#xff08;2&#xff09;其中一方关机…

Ubuntu系统提示“/dev/mmcblk0p1 分区满了‘以及磁盘空间不够的处理办法

查看boot分区使用空间&#xff1a; df 查看已安装的内核版本&#xff1a; dpkg --get-selections | grep linux &#xff08;其中带image的一般就是旧版本&#xff0c;deinstall代表已经删除的旧版本&#xff0c;install代表还未删除的旧版本内核&#xff09; 查看系统当前…

基于java+springboot+vue实现的健身房管理系统(文末源码+Lw+ppt)23-523

摘 要 健身房管理的以往工作流程繁杂、多样、管理复杂与设备维护繁琐。而如今计算机已完全能够胜任健身房管理工作&#xff0c;而且更加准确、方便、快捷、高效、清晰、透明&#xff0c;它完全可以克服以上所述的不足之处。这将给查询信息和管理带来很大的方便&#xff0c;从…

晶体管测试仪系统能测 IGBT. Mosfet. Diode. BJT......

晶体管测试仪系统能测试很多电子元器件的静态直流参数&#xff08;如击穿电压V(BR)CES/V(BR)DSs、漏电流ICEs/lGEs/IGSs/lDSs、阈值电压/VGE(th)、开启电压/VCE(on)、跨导/Gfe/Gfs、压降/Vf、导通内阻Rds(on)&#xff09;。 测试种类覆盖 7 大类别26分类&#xff0c;包括“二极…

Redis 更新开源许可证 - 不再支持云供应商提供商业化的 Redis

原文&#xff1a;Rowan Trollope - 2024.03.20 未来的 Redis 版本将继续在 RSALv2 和 SSPLv1 双许可证下提供源代码的免费和宽松使用&#xff1b;这些版本将整合先前仅在 Redis Stack 中可用的高级数据类型和处理引擎。 从今天开始&#xff0c;所有未来的 Redis 版本都将以开…

力扣454. 四数相加 II

思路&#xff1a;把四个数组拆成两对&#xff0c;两个分别相加&#xff0c;记录第一对的相加结果进map里&#xff0c;再把第二对数组 0-nums2-nums4 去map里面找出现了几次&#xff0c;这题不用对重复的四元组去重&#xff0c;所以出现多次都有效。 class Solution {public int…