剑指offer32Ⅰ:从上到下打印二叉树

news2024/11/16 13:43:51

    题目描述

从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
例如:

给定二叉树: [3,9,20,null,null,15,7],

    3
   / \
  9  20
      /  \
   15   7
   
返回其层次遍历结果:

[3,9,20,15,7]

提示:

节点总数 <= 1000

   思路

     这个题目的意思很明确,就是从根节点开始,一层一层打印节点,而且节点顺序是从左到右。以上面示例为例,3为根节点,之后打印它的左右节点9,20,之后再打印20的子节点15,7。全部打印完成结束。

   这道题有点类似图算法中的广度优先搜索,先从顶端开始,依次遍历图的下一层节点,下一层节点遍历完成,接着遍历下下一层。仅仅依赖树结构的左右节点关系,然后递归遍历,我们无法得到最终结果,因为随着层数的增加,兄弟节点之间没有必然关系,他们无法保证从左到右来遍历。

    这里我们需要借助一个队列来存放遍历过的节点,这样,每遍历依次,后续的遍历,我们从队列开头取元素,这样就可以保证按照层级和左右顺序来打印树节点。

 代码

package com.xxx.example;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class Offer32PrintTreeNode {
    private static TreeNode root;
    private static List<List<Integer>> nodeList = new ArrayList<>();

    public static void main(String[] args) {
        TreeNode treeNode = new TreeNode(3);
        TreeNode treeNode1 = new TreeNode(9);
        TreeNode treeNode2 = new TreeNode(20);
        TreeNode treeNode3 = new TreeNode(15);
        TreeNode treeNode4 = new TreeNode(7);
        root = treeNode;
        treeNode2.left = treeNode3;
        treeNode2.right = treeNode4;
        root.left = treeNode1;
        root.right = treeNode2;

        int[] result = levelOrder(root);

        for(int i=0;i<result.length;i++) {
            System.out.print(result[i] + " ");
        }
        System.out.println();

    }

    public static int[] levelOrder(TreeNode root) {
        if (root == null)
            return new int[0];
        Queue<TreeNode> queue = new LinkedList<>();
        ArrayList<Integer> list = new ArrayList<>();
        queue.add(root);
        while (!queue.isEmpty()) {
            TreeNode curNode = queue.poll();
            list.add(curNode.val);
            if (curNode.left != null)
                queue.add(curNode.left);
            if (curNode.right != null)
                queue.add(curNode.right);
        }
        return list.stream().mapToInt(Integer::intValue).toArray();
    }


}

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int value) {
        this.val = value;
        this.left = null;
        this.right = null;
    }

    @Override
    public String toString() {
        return val + "";
    }
}

    还有一种办法,其实就是利用深度优先搜索的思想解决,这个似乎有点玄妙,这里明明是要广度优先搜索,怎么还利用起深度优先搜索呢?其实是这样的,这里按照深度优先搜索,我们只是把搜到的数据打上标签,这个标签就是它的层次,也叫深度,每个深度的节点我们保存到同样深度的map映射里。最后,我们遍历map,得到所有按照层次组织的节点,这样就是从上到下,从左到右打印二叉树节点。 

深度优先搜索 


package com.xxx.tutorial;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TreeNodeTraversal {

    private static Map<Integer, List<Integer>> map = new HashMap<>();
    private static int max = -1;
    private static int cnt = 0;

    public static void main(String[] args) {
        TreeNode node0 = new TreeNode(3);
        TreeNode node1 = new TreeNode(9);
        TreeNode node2 = new TreeNode(20);
        TreeNode node3 = new TreeNode(15);
        TreeNode node4 = new TreeNode(7);

        node0.left = node1;
        node0.right = node2;
        node2.left = node3;
        node2.right = node4;
        int[] res = traversal(node0);
        for (int i = 0; i < res.length; i++) {
            System.out.print(res[i] + " ");
        }
        System.out.println();
    }

    public static int[] traversal(TreeNode root) {
        dfs(root, 0);
        int[] ans = new int[cnt];
        for (int i = 0, idx = 0; i <= max; i++) {
            for (int x : map.get(i))
                ans[idx++] = x;
        }
        return ans;
    }

    public static void dfs(TreeNode node, int depth) {
        if (node == null) return;
        max = Math.max(max, depth);
        cnt++;
        dfs(node.left, depth + 1);
        List<Integer> list = map.getOrDefault(depth, new ArrayList<>());
        list.add(node.val);
        map.put(depth, list);
        dfs(node.right, depth + 1);
    }

    public static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        public TreeNode(int value) {
            this.val = value;
            this.left = null;
            this.right = null;
        }
    }
}

    这里通过递归调用,我们能遍历完所有节点,并按照深度层次保存各自深度的节点。 

    这个思路很巧妙,它利用深度层次来映射对应的节点,最后,我们遍历map映射得到所有节点,他们的顺序正好是从上到下,从左到右。

    剑指offer打印二叉树还有另一个题目,就是按照层次打印二叉树,就是[[3],[9,20],[15,7]],相信经过上面的深度优先搜索,大家也许有一些想法,这个代码或许简单改造一下就可以了。

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

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

相关文章

LeetCode每日一题:2251. 花期内花的数目(2023.9.28 C++)

目录 2251. 花期内花的数目 题目描述&#xff1a; 实现代码与解析&#xff1a; 离散化差分 原理思路&#xff1a; 2251. 花期内花的数目 题目描述&#xff1a; 给你一个下标从 0 开始的二维整数数组 flowers &#xff0c;其中 flowers[i] [starti, endi] 表示第 i 朵花的…

pytorch函数reshape()和view()的区别及张量连续性

目录 1.view() 2.reshape() 3.引用和副本&#xff1a; 4.区别 5.总结 在PyTorch中&#xff0c;tensor可以使用两种方法来改变其形状&#xff1a;view()和reshape()。这两种方法的作用是相当类似的&#xff0c;但是它们在实现上有一些细微的区别。 1.view() view()方法是…

【C++】C++继承——切片、隐藏、默认成员函数、菱形

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;C学习 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 上一篇博客&#xff1a;【C】STL…

行为型设计模式——责任链模式

摘要 责任链模式(Chain of responsibility pattern): 通过责任链模式, 你可以为某个请求创建一个对象链. 每个对象依序检查此请求并对其进行处理或者将它传给链中的下一个对象。 一、责任链模式意图 职责链模式&#xff08;Chain Of Responsibility&#xff09; 是一种行为设…

Uniapp实现APP云打包

一. 基础配置 二. APP图标配置 1. 点击浏览 选取图标(注&#xff1a;图片格式为png) 2. 点击自动生成所有图标并替换 三. 点击发行 并选择云打包 四. 去开发者中心获取证书 我这里是已经获取好的&#xff0c;没有获取的话&#xff0c;按照提示获取即可&#xff0c;非常简单…

axios和vite在本地开发环境配置代理的两种方式,五分钟学会

如果你使用vue或者react开发&#xff0c;就得使用axios吧&#xff0c;然后为了解决跨域问题&#xff0c;就得使用vite配置吧&#xff0c;那怎么协调配置它们两个才能正常工作呢&#xff1f; 正常的流程&#xff1a;配置axios的baseURL&#xff0c;然后配置vite的proxy 第一种…

【论文阅读】Directional Connectivity-based Segmentation of Medical Images

目录 摘要介绍方法效果结论 论文&#xff1a;Directional Connectivity-based Segmentation of Medical Images 代码&#xff1a;https://github.com/zyun-y/dconnnet 摘要 出发点&#xff1a;生物标志分割中的解剖学一致性对许多医学图像分析任务至关重要。 之前工作的问题&…

Linux 实训4 正则表达式

将实训4 &#xff1a;正则表达式的完成情况提交实验报告。 创建并输入文本文件 a bcd 1 233 abc123 defrt456 123abc 12568teids abcfrt568 "Open Source" is a good mechan1sm to develop programs. apple is my favorite food. Football game is not …

数据结构----结构--非线性结构--树

数据结构----结构–非线性结构–树 一.树&#xff08;Tree&#xff09; 1.树的结构 树是一对多的结构 2.关于树的知识点 1.根节点&#xff1a;树最上面的节点 2.中间节点&#xff1a;树中间的节点 3.叶子节点&#xff1a;树最下面的节点 如下图 4.边&#xff1a;在树中…

弱信号的采样与频谱分析(修订中...)

1.频谱混叠效应 - 波形数据抽样 这是一组经过抽样的数据的频谱&#xff0c;红圈圈出的两条谱线&#xff0c;是我们需要关注的特征谱线。这个信号与右侧的临近信号比较&#xff0c;求频率比值&#xff0c;比值恒定与理论推导相符。再5取1降低采样率后&#xff0c;大致相同的频率…

虹科案例 | 虹科MSR实现易碎艺术品安全运输——开发有效减少冲击和振动的新工艺

【案例】在CTI研究项目中使用带有加速度传感器的虹科MSR165数据记录仪对冲击振动进行风险评估 项目背景&#xff1a; 全球艺术品运输量持续增长。在运输过程中&#xff0c;画作面临着诸多压力和风险&#xff0c;如冲击和振动。在博物馆搬运这些画作、装卸包装箱、卡车在颠簸的…

Android 视频通话分析总结

1、WireShark 解析视频流 1.1 安装插件 下载rtp_h264_extractor.lua文件&#xff0c;放入Wireshark安装目录 下载地址&#xff1a;https://download.csdn.net/download/tjpuzm/88381821 在init.lua中添加如下代码 dofile(DATA_DIR.."rtp_h264_extractor.lua") 重新…

淘宝的数据使用和数字化进阶过程

宝在数字化转型的过程中&#xff0c;数据使用和数字化进阶均经历了几个不同的发展阶段&#xff0c;这些经历对致力于数字化转型的企业有更多借鉴意义。 1 淘宝数据API使用的5个阶段 淘宝的数据使用经历了5个阶段&#xff0c;如图所示&#xff0c;以下分别进行介绍。 1.依靠数…

苹果手机数据恢复软件哪款好用?看到就是赚到!

手机中储存的数据包含了许多重要的照片、视频、文件等&#xff0c;更重要的是这些数据中所承载着的珍贵记忆。但在我们使用手机的过程中&#xff0c;难以避免一些意外&#xff0c;手机中的数据可能会因为误删除、手机故障、手机恢复出厂设置等原因丢失。 这时候&#xff0c;如…

[chrome devtools]Console面板

点解开发者工具控制台【Console】后&#xff0c;在最右侧找到点击出现如下面板&#xff1a; 【1】是否在控制台显示网络相关的日志信息&#xff0c;比如get请求 【2】刷新或者跳转页面时&#xff0c;原先控制台已显示的日志是否继续保留在控制台上&#xff0c;就是刷新页面控…

批处理数值计算实战,以及打印乘法表

文章目录 计算2的N次方转二进制最大公约数和最小公倍数打印乘法表 计算2的N次方 二进制转换是经常遇到的一个需求&#xff0c;批处理可以非常便捷地完成这个工作。而二进制转化过程中&#xff0c;第一步就是和 2 n 2^n 2n比较大小&#xff0c;所以在实现这个功能之前&#xff…

基于微信小程序的自驾游拼团小程序的设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

15. RocketMQ 消息队列

Spring Cloud 微服务系列文章&#xff0c;点击上方合集↑ 1. 简介 RocketMQ是一款开源的分布式消息中间件&#xff0c;它具有高可靠性、高性能和可伸缩性&#xff0c;被广泛用于构建分布式系统中的可靠消息传递服务。 官网地址&#xff1a; https://rocketmq.apache.org/ 2…

使用超声波清洗机洗眼镜有哪些注意事项、高颜值超声波清洗机推荐

眼镜&#xff0c;对于许多人来说&#xff0c;不仅仅是矫正视力的工具&#xff0c;更是日常生活的重要伴侣。但是&#xff0c;眼镜的清洁问题却常常让人感到困扰。镜片上的污渍、指纹、甚至小划痕&#xff0c;都让眼镜的使用体验大打折扣。幸运的是&#xff0c;随着科技的进步&a…

优化Python开发环境的几个神技巧

用Python编代码体验极佳&#xff0c;并且随着新版本的发布越来越好&#xff01; 对于很多人而言&#xff0c;Python提供的大量免费函数库、高可读性的程序和新引入的类型注释让很多爱不释手。 然而&#xff0c;数据科学家特别容易使自己的Jupyter notebook变得庞大而杂乱&…