day15|各种遍历的应用

相关题目:
层次遍历会一打十
反转二叉树
对称二叉树

层次遍历会一打十

自底向上的层序遍历

在这里插入图片描述
实现思路:层次遍历二叉树,将遍历后的结果revers即可

public List<List<Integer>> levelOrderBottom(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        Queue<TreeNode> que = new ArrayDeque<>();
        if (root == null) {
            return res;
        }
        que.offer(root);
        int size = 0;
        while (!que.isEmpty()) {
            size = que.size();
            List<Integer> list = new ArrayList<>();
            while (size > 0) {
                TreeNode cur = que.poll();
                list.add(cur.val);
                if (cur.left != null) {
                    que.offer(cur.left);
                }
                if (cur.right != null) {
                    que.offer(cur.right);
                }

                size--;
            }
            res.add(list);
        }
        Collections.reverse(res);
        return res;
    }

输出二叉树的右视图节点

在这里插入图片描述
实现思路:层次遍历二叉树,记录二叉树每一层的节点数,到达该层最后一个节点时,将其加入到结果集即可

public List<Integer> rightSideView(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if(root == null){
            return res;
        }
        Queue<TreeNode> que = new ArrayDeque<>();
        que.offer(root);
        int size = 0;
        while(!que.isEmpty()){
            size = que.size();
            while(size>0){
                TreeNode cur = que.poll();
                //遍历到该层最后一个节点
                if(size == 1){
                    res.add(cur.val);
                }
                if(cur.left!=null){
                    que.offer(cur.left);
                }
                if(cur.right!=null){
                    que.offer(cur.right);
                }
                size--;
            }
        }
        return res;
    }

二叉树每层的平均值

在这里插入图片描述
实现思路:层次遍历二叉树,计算每一层的平均值,注意:每层数之和及平均值的数据类型

public List<Double> averageOfLevels(TreeNode root) {
        List<Double> res = new ArrayList<>();
        Queue<TreeNode> que = new ArrayDeque<>();
        if(root == null){
            return res;
        }
        int size = 0;
        que.offer(root);
        while(!que.isEmpty()){
            size = que.size();
            double sum = 0;
            for (int i = 0; i < size; i++) {
                TreeNode cur = que.poll();
                sum += cur.val;
                if(cur.left!=null){
                    que.offer(cur.left);
                }
                if(cur.right!=null){
                    que.offer(cur.right);
                }
            }
            res.add(sum/size);
        }
        return res;
    }

N叉树的·层次遍历

在这里插入图片描述

class Node {
    public int val;
    public List<Node> children;

    public Node() {
    }

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
};

public class LevelOrderNode {
    public List<List<Integer>> levelOrder(Node root) {
        List<List<Integer>> res = new ArrayList<>();
        if (root == null) {
            return res;
        }
        Queue<Node> que = new ArrayDeque<>();
        que.offer(root);
        while (!que.isEmpty()) {
            int size = que.size();
            List<Integer> list = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                Node cur = que.poll();
                list.add(cur.val);
                List<Node> children = cur.children;
                if (children == null || children.size() == 0) {
                    continue;
                }
                for (Node child : children) {
                    if (child != null) {
                        que.offer(child);
                    }
                }
            }
            res.add(list);
        }
        return res;
    }

}

在二叉树的每一行中找最大值

在这里插入图片描述
实现思路:层次遍历二叉树,记录每一层的最大值

public List<Integer> largestValues(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if(root == null){
            return res;
        }
        Queue<TreeNode> que = new ArrayDeque<>();
        int size = 0;
        que.offer(root);
        while(!que.isEmpty()){
            size = que.size();
            int max = Integer.MIN_VALUE;
            while(size>0) {
                TreeNode cur = que.poll();
                max = Math.max(max,cur.val);
                if(cur.left!=null){
                    que.offer(cur.left);
                }
                if(cur.right!=null){
                    que.offer(cur.right);
                }
                size--;
            }
            res.add(max);
        }
        return res;
    }

填充每个节点的下一个右侧节点指针

在这里插入图片描述
实现思路:层次遍历二叉树,记录每层元素个数,遍历每层元素,元素个数大于1时,使其next指针指向队头元素;元素个数为1时,使其next指针指向null即可

class NodeText {
    public int val;
    public NodeText left;
    public NodeText right;
    public NodeText next;

    public NodeText() {}

    public NodeText(int _val) {
        val = _val;
    }

    public NodeText(int _val, NodeText _left, NodeText _right, NodeText _next) {
        val = _val;
        left = _left;
        right = _right;
        next = _next;
    }
};
public class Connect {
    public NodeText connect(NodeText root) {
        Queue<NodeText> que = new ArrayDeque<>();
        if(root == null){
            return root;
        }
        que.offer(root);
        while(!que.isEmpty()){
            int size = que.size();
            while(size>0){
                NodeText cur = que.poll();
                if(size>1){
                    NodeText temp = que.peek();
                    cur.next = temp;
                }
                else{
                    cur.next =null;
                }
                if(cur.left!=null){
                    que.offer(cur.left);
                }
                if(cur.right!=null){
                    que.offer(cur.right);
                }
                size--;
            }
        }
        return root;
    }
}

求二叉树的最大深度

在这里插入图片描述
实现思路:层次遍历二叉树,记录树的层数

public int maxDepth(TreeNode root) {
        int maxDepth = 0;
        int size = 0;
        if(root == null){
            return 0;
        }
        Queue<TreeNode> que = new ArrayDeque<>();
        que.offer(root);
        while(!que.isEmpty()){
            maxDepth++;
            size = que.size();
            while(size>0){
                TreeNode cur = que.poll();
                if(cur.left!=null){
                    que.offer(cur.left);
                }
                if(cur.right!=null){
                    que.offer(cur.right);
                }
                size--;
            }
        }
        return maxDepth;
    }

求二叉树的最小深度

在这里插入图片描述

实现思路:层次遍历二叉树,当某个节点的左右孩子均为null时,输出该节点所在层数,及就是树的最小深度

public int minDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int deep = 0;
        int size = 0;
        Queue<TreeNode> que = new ArrayDeque<>();
        que.offer(root);
        while (!que.isEmpty()) {
            deep++;
            size = que.size();
            while (size > 0) {
                TreeNode cur = que.poll();
                if (cur.left == null && cur.right == null) {
                    return deep;
                } else {
                    if (cur.left != null) {
                        que.offer(cur.left);
                    }
                    if (cur.right != null) {
                        que.offer(cur.right);
                    }
                }
                size--;
            }
        }
        return deep;
    }

反转二叉树(掌握递归遍历)

实现方法:使用前序遍历、后序遍历及其层次遍历均可实现
前序遍历实现方法:遍历中间节点,中间节点的左右孩子交换位置即可
后序遍历实现方法:遍历的左子树和右子树,交换中间节点左右孩子交换位置即可
层次遍历:遍历每一层的各个节点,反转各个节点的左右孩子即可

public class InvertTree extends TreeNode {
    public TreeNode invertTree(TreeNode root) {
        if(root == null){
            return null;
        }
//        //前序
//        swap(root);
//        invertTree(root.left);
//        invertTree(root.right);

//        //后序
//        invertTree(root.left);
//        invertTree(root.right);
//        swap(root);
        //层次遍历--迭代
        Queue<TreeNode> que = new ArrayDeque<>();
        int size = 0;
        que.offer(root);
        while(!que.isEmpty()){
            size = que.size();
            while(size>0){
                TreeNode cur = que.poll();
                swap(cur);
                if(cur.left!=null){
                    que.offer(cur.left);
                }
                if(cur.right!=null){
                    que.offer(cur.right);
                }
                size--;
            }
        }

        return root;
    }
    public void swap(TreeNode root){
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
}

对称二叉树

递归实现:
递归三部曲

  1. 确定递归函数的参数和返回值
    因为我们要比较的是根节点的两个子树是否是相互翻转的,进而判断这个树是不是对称树,所以要比较的是两个树,参数自然也是左子树节点和右子树节点。
    返回值自然是bool类型。
    代码如下:
    bool compare(TreeNode* left, TreeNode* right)
  2. 确定终止条件
    要比较两个节点数值相不相同,首先要把两个节点为空的情况弄清楚!否则后面比较数值的时候就会操作空指针了。
    节点为空的情况有:(注意我们比较的其实不是左孩子和右孩子,所以如下我称之为左节点右节点)
  • 左节点为空,右节点不为空,不对称,return false
  • 左不为空,右为空,不对称 return false
  • 左右都为空,对称,返回true
  • 左右都不为空,比较节点数值,不相同就return false
    代码如下:
if (left == NULL && right != NULL) return false;
else if (left != NULL && right == NULL) return false;
else if (left == NULL && right == NULL) return true;
else if (left->val != right->val) return false; // 注意这里我没有使用else

注意上面最后一种情况,我没有使用else,而是else if, 因为我们把以上情况都排除之后,剩下的就是 左右节点都不为空,且数值相同的情况。
3. 确定单层递归的逻辑
此时才进入单层递归的逻辑,单层递归的逻辑就是处理 左右节点都不为空,且数值相同的情况。

  • 比较二叉树外侧是否对称 :传入的是左节点的左孩子,右节点的右孩子。
  • 比较内侧是否对称:传入左节点的右孩子,右节点的左孩子。

如果左右都对称就返回true ,有一侧不对称就返回false 。
实现过程:

class Solution {
    public boolean isSymmetric(TreeNode root) {
        if (root == null) {
            return true;
        }
        return compare(root.left,root.right);
    }

    //递归实现
    public boolean compare(TreeNode left, TreeNode right) {
        if (left == null && right != null) return false;
        else if (left != null && right == null) return false;
        else if (left != null && right != null && left.val != right.val) return false;
        else if (left == null && right == null) return true;
        boolean inside = compare(left.left, right.right);
        boolean outside = compare(left.right, right.left);
        return inside && outside;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu22部署Docker私有仓库Harbor (http https方式)

harbor日志&#xff1a;/var/log/harbor 前置安装配置 需先安装docker和docker-compose&#xff1a; 0.配置清华大学apt源并安装docker #信任 Docker 的 GPG 公钥: sudo apt-get install ca-certificates curl gnupg curl -fsSL https://download.docker.com/linux/ubunt…

Talkingdata 数据统计

TalkingData 是一家提供移动大数据服务的平台&#xff0c;专注于为客户提供全面的产品统计分析服务和权威的移动行业数据解析。通过集成 TalkingData 的 SDK&#xff0c;开发者可以收集、处理和分析其应用的一方数据&#xff0c;从而深入了解用户的使用行为、应用表现及市场动态…

Java面试八股之什么是死锁

什么是死锁 死锁&#xff08;Deadlock&#xff09;是多线程编程中的一种常见问题&#xff0c;特别是在涉及到资源共享和同步的时候。具体来说&#xff0c;死锁是指两个或两个以上的线程在执行过程中&#xff0c;由于互相持有并等待对方释放的资源&#xff0c;而导致所有线程都…

IP地址显示“不安全”怎么办|已解决

解决IP地址显示“不安全”的问题&#xff0c;通常需要确保网站或服务使用HTTPS协议进行加密通信&#xff0c;可以通过部署SSL证书来解决&#xff0c;以下是具体的解决步骤&#xff1a; 1 申请IP地址SSL证书&#xff1a;网站管理员应向证书颁发机构&#xff08;CA&#xff09;申…

http项目改为/支持https的方案、无需修改后台代码

背景描述&#xff1a;原来的项目前后台都是http&#xff0c;现在某个服务要求前台必须使用https&#xff1b; 方案1&#xff1a;前台部署在https里&#xff0c;后面代码修改&#xff1b;但是微服务架构&#xff0c;后台工作量太大&#xff1b; 方案2&#xff1a;前台部署在ht…

【linux特殊符号】

文章目录 学习目标一、Linux的特殊符号1.系统变量2.引号 总结 学习目标 1.学会查看系统变量 2.学会各种引号 3.一、Linux的特殊符号 1.系统变量 windows系统变量&#xff1a;echo %path% linux系统变量&#xff1a;echo $PATH2.引号 " " 双引号&#xff0c;换行…

AJAX(JQuery版本)

目录 前言 一.load方法 1.1load()简介 1.2load()方法示例 1.3load()方法回调函数的参数 二.$.get()方法 2.1$.get()方法介绍 2.2详细说明 2.3一些例子 2.3.1请求test.php网页并传送两个参数 2.3.2显示test返回值 三.$.post()方法 3.1$.post()方法介绍 3.2详细说明 …

JVM学习-垃圾回收(三)

System.gc 通过System.gc()或Runtime.getRuntime().gc()的调用&#xff0c;会显示触发Full GC&#xff0c;同时对老年代和方法区进行回收&#xff0c;尝试释放被丢弃对象占用的内存然后System.gc()调用附带一个免责声明&#xff0c;无法保证对垃圾收集器的调用JVM实现者可以通…

瑞芯微RV1126——交叉编译与移植

一、搭建这个nfs服务挂载 (1) sudo apt install nfs-kernel-server (2) 然后在你的ubuntu创建一个nfs共享目录&#xff1a; (3) sudo /etc/init.d/nfs-kernel-server restart 重启nfs服务 (4) 修改配置文件: sudo vim /etc/exports 在这个配置文件里面添加&#xff1a;/hom…

Vue状态管理深度剖析:Vuex vs Pinia —— 从原理到实践的全面对比

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 &#x1f44b; 引言&#x1f4cc; Vuex 基础知识核心构成要素示例代码 &#x1f4cc; Pinia 基础知识核心构成要素示例代码 &#x1f4cc; Vuex与Pinia的区别&#x1f4cc; 使用示例与对比&#x1f4cc; 总结 &#x1f44b;…

【Linux学习】进程间通信 (1) —— 管道

下面是有关进程通信中管道的相关介绍&#xff0c;希望对你有所帮助&#xff01; 小海编程心语录-CSDN博客 1. 进程通信的基本概念 1.1 概念 进程间通信简称 IPC &#xff0c;指两个进程之间的通信。 IPC的方式通常有管道&#xff08;包括无名管道和命名管道&#xff09;、消息…

复现Apache HTTPD 多后缀解析漏洞

准备一个纯净的Ubuntu系统 1.先更新一下安装列表 sudo apt-get update 2.安装dockers.io sudo apt install docker.io 查看是否安装成功 docker -v 3. 查看是否安装pip,没有的话就安装 sudo apt-get install python3-pip 4. 安装docker-compose pip install docker-comp…

性能测试工具

性能测试工具 1.Jmeter 环境搭建1.安装JDK2.安装Jmeter1.下载2.安装3.环境配置 3.Jmeter 文件目录介绍1.bin目录2.docs 目录3.printable_docs目录4.lib目录 4.修改默认配置1.汉化配置2.修改主题 5.元件的基本介绍6.元件的作用域作用域的原则 7.元件的执行顺序 1.Jmeter 环境搭建…

Axure RP 9 for Mac/win:重新定义交互原型设计的未来

在当今数字化时代&#xff0c;交互原型设计已成为产品开发中不可或缺的一环。Axure RP 9作为一款功能强大的交互原型设计软件&#xff0c;凭借其出色的性能和用户友好的界面&#xff0c;赢得了广大设计师的青睐。 Axure RP 9不仅支持Mac和Windows两大主流操作系统&#xff0c;…

C#数据类型变量、常量

一个变量只不过是一个供程序操作的存储区的名字。 在 C# 中&#xff0c;变量是用于存储和表示数据的标识符&#xff0c;在声明变量时&#xff0c;您需要指定变量的类型&#xff0c;并且可以选择性地为其分配一个初始值。 在 C# 中&#xff0c;每个变量都有一个特定的类型&…

三能一体运营体系助力政企支撑水平提升

生产力的发展是现代社会孜孜不倦的追求&#xff0c;由此产生了我们熟悉的“机械化、电子化、信息化”乃至现今正在发生的“智能化”四次工业革命。这些是由技术的突破性发展带来的&#xff0c;但我们也注意到生产力发展的另一个助力&#xff0c;即生产效率的提升&#xff0c;19…

指数分布的理解,推导与应用

指数分布的定义 在浙大版的教材中&#xff0c;指数分布的定义如下&#xff1a; 若连续型的随机变量 X X X的概率密度为&#xff1a; f ( x ) { 1 θ e − x θ , x>0 0 , 其他 f(x) \begin{cases} \frac{1}{\theta} e^{-\frac{x}{\theta}}, & \text{x>0}\\ 0, &a…

编程基础:掌握运算符与优先级

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、运算符的基石&#xff1a;加减乘除 二、比较运算符&#xff1a;判断数值大小 三、整除…

Tensorflow入门实战 P01-实现手写数字识别mnist

目录 1、背景&#xff1a;MNIST手写数字识别 2、完整代码&#xff08;Tensorflow&#xff09;&#xff1a; 3、运行过程及结果&#xff1a; 4、小结&#xff08;还是很清晰的&#xff09; 5、 展望 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客…

智慧水务可视化大屏,一屏纵览水务信息。

智慧水务可视化大屏通常需要展现以下几类信息&#xff1a; 01.实时监测数据&#xff1a; 包括水源水质、水压、水位、水流速等实时监测数据&#xff0c;通过图表、曲线等形式展示&#xff0c;帮助监测人员了解当前水务系统的运行状态。 02.设备运行状态&#xff1a; 展示水泵…