代码随想录第十五天| ● 层序遍历 10 ● 226.翻转二叉树 ● 101.对称二叉树

文章目录

  • 层序遍历
    • 102. 二叉树的层序遍历
      • 思路一:递归
      • 思路二:层序遍历-迭代-借助队列
    • 107. 二叉树的层序遍历 II
      • 思路:层序遍历后翻转数组result即可
    • 199.二叉树的右视图
      • 思路:通过list数组储存每一层末尾值
    • 637.二叉树的层平均值
      • 思路:通过list数组储存均值
    • 429.N 叉树的层序遍历
      • 思路:依次判断并储存孩子节点
    • 515.在每个树行中找最大值
      • 思路:每一层储存最大值Integer.MIN_VALUE
    • 116.填充每个节点的下一个右侧节点指针
      • 思路
    • 117.填充每个节点的下一个右侧节点指针II
      • 思路:【和前一题相同】
    • 104.二叉树的最大深度
      • 思路:每层deep+1
    • 111.二叉树的最小深度
      • 思路:
  • 226.翻转二叉树
    • 1.递归法DFS
      • 代码
    • 2.层序遍历BFS
      • 代码:
  • 101. 对称二叉树
    • 思路:-使用后序遍历 左右中
      • 递归法
      • 递归代码

层序遍历

层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。这种遍历的方式和我们之前讲过的都不太一样。

需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。

而这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上

使用队列实现二叉树广度优先遍历,动画如在这里插入图片描述

102. 二叉树的层序遍历

在这里插入图片描述

思路一:递归

/*** 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 {public List<List<Integer>> resList = new ArrayList<>();public List<List<Integer>> levelOrder(TreeNode root) {DFS(root,0);return resList;}//递归public void DFS(TreeNode root,Integer deep){if(root==null)return; //终止条件deep++;if(resList.size()<deep){//当层级增加时,list的Item也增加,利用list的索引值进行层级界定// 每一层一个item储存对应层的节点元素List<Integer> item = new ArrayList<>();resList.add(item);}resList.get(deep-1).add(root.val);//根据对应的层数储存节点DFS(root.left,deep);DFS(root.right,deep);}
}

思路二:层序遍历-迭代-借助队列

先建立【储存每一层的result数组】
【建立队列】保存每一层的树节点,方便取值。
将root放入队列中,队列不为空时进行循环。
建立每一层的item数组,储存数值
题解
在这里插入图片描述
代码:
注意: queue的size一定要提前固定,因为queue的大小是动态变化的

class Solution {public List<List<Integer>> levelOrder(TreeNode root) {Queue<TreeNode>queue = new LinkedList<>();List<List<Integer>> res = new ArrayList<>();if(root!=null){queue.add(root);//放入根节点}while(!queue.isEmpty()){// 新建一个临时列表 tmp ,用于存储当前层打印结果List<Integer> tmp=new ArrayList<>();// 队列放入每一层节点的个数// 循环次数为当前层节点数// // 这里一定要使用固定大小size,不要使用que.size(),因为que.size是不断变化的int len=queue.size();for(int i=len;i>0;i--){TreeNode node=queue.poll();tmp.add(node.val);if(node.left!=null){queue.add(node.left);}if(node.right!=null){queue.add(node.right);}}res.add(tmp);}return res;}
}

107. 二叉树的层序遍历 II

在这里插入图片描述

思路:层序遍历后翻转数组result即可

class Solution {public List<List<Integer>> levelOrderBottom(TreeNode root) {Queue<TreeNode> queue = new LinkedList<>();List<List<Integer>> res = new ArrayList<>();if(root!=null){queue.add(root);}while(!queue.isEmpty()){List<Integer> tmp = new ArrayList<>();int len = queue.size();for(int i=len;i>0;i--){TreeNode node = queue.poll();tmp.add(node.val);if(node.left!=null){queue.add(node.left);}if(node.right!=null){queue.add(node.right);}}res.add(tmp);}// return res;List<List<Integer>> res1 = new ArrayList<>();for(int i=res.size()-1;i>=0;i--){res1.add(res.get(i));}return res1;}
}

199.二叉树的右视图

在这里插入图片描述

思路:通过list数组储存每一层末尾值

层序遍历的时候,判断是否遍历到单层的最后面的元素,如果是,就放进result数组中,随后返回result就可以了。

/*** 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 {public List<Integer> rightSideView(TreeNode root) {// List<List<Integer>> res = new ArrayList<>();Queue<TreeNode> queue = new LinkedList<>();if(root!=null){queue.add(root);}List<Integer>list=new ArrayList<>();//储存最终结果while(!queue.isEmpty()){int len=queue.size();// List<Integer>temp=new ArrayList<>();for(int i=len;i>0;i--){TreeNode node=queue.poll();if(i==1){//浏览到数组的最后一个,储存list.add(node.val);}if(node.left!=null){queue.add(node.left);}if(node.right!=null){queue.add(node.right);}}}return list;}
}

637.二叉树的层平均值

在这里插入图片描述

思路:通过list数组储存均值

本题就是层序遍历的时候把一层求个总和在取一个均值。

/*** 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 {public List<Double> averageOfLevels(TreeNode root) {Queue<TreeNode> queue = new LinkedList<>();List<Double> list = new ArrayList<>();if(root!=null){queue.add(root);}while(!queue.isEmpty()){// List<Integer> list = new ArrayList<>();int len = queue.size();double temp=0;for(int i=len;i>0;i--){TreeNode node = queue.poll();// list.add(node.val);temp+=node.val;if(node.left!=null){queue.add(node.left);}if(node.right!=null){queue.add(node.right);}}list.add(temp/len);}return list;}
}

429.N 叉树的层序遍历

在这里插入图片描述

思路:依次判断并储存孩子节点

注意:

                // List<Node> children = node.children;// if(children==null||children.size()==0){//     continue;// }// for(Node child:children){或者 两种方法for(Node child:node.children){if(child!=null){queue.add(child);}}
/*
// Definition for a Node.
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;}
};
*/class Solution {public List<List<Integer>> levelOrder(Node root) {List<List<Integer>> res=new ArrayList<>();Queue<Node> queue =new LinkedList<>();if(root!=null){queue.add(root);}while(!queue.isEmpty()){List<Integer> item = new ArrayList<>();int len=queue.size();for(int i=0;i<len;i++){Node node=queue.poll();item.add(node.val);// List<Node> children = node.children;// if(children==null||children.size()==0){//     continue;// }for(Node child:node.children){if(child!=null){queue.add(child);}}}res.add(item);}return res;}
}

515.在每个树行中找最大值

在这里插入图片描述

思路:每一层储存最大值Integer.MIN_VALUE

/*** 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 {public List<Integer> largestValues(TreeNode root) {List<Integer> res = new ArrayList<>();Queue<TreeNode> queue = new LinkedList<>();if(root!=null){queue.add(root);}while(!queue.isEmpty()){int len=queue.size();int num=Integer.MIN_VALUE;for(int i=0;i<len;i++){TreeNode node = queue.poll();num=Math.max(num,node.val);if(node.left!=null){queue.add(node.left);}if(node.right!=null){queue.add(node.right);}}res.add(num);}return res;}
}

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

在这里插入图片描述

思路

本题依然是层序遍历,只不过在单层遍历的时候记录一下本层的头部节点,然后在遍历的时候让前一个节点指向本节点就可以了

class Solution {public Node connect(Node root) {Queue<Node>queue = new LinkedList<>();if(root!=null){queue.add(root);}while(!queue.isEmpty()){int len=queue.size();Node pre=null;Node node =null;for(int i=0;i<len;i++){if(i==0){//记录头部节点pre=queue.poll();node=pre;}else{//让头部节点指向本节点node=queue.poll();pre.next=node;pre=pre.next;}if(node.left!=null){queue.add(node.left);}if(node.right!=null){queue.add(node.right);}}pre.next=null;}return root;}
}

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

在这里插入图片描述

思路:【和前一题相同】

104.二叉树的最大深度

在这里插入图片描述

思路:每层deep+1

class Solution {public int maxDepth(TreeNode root) {Queue<TreeNode>queue = new LinkedList<>();int deep=0;if(root!=null){queue.add(root);}while(!queue.isEmpty()){deep++;int len=queue.size();for(int i=0;i<len;i++){TreeNode node = queue.poll();if(node.left!=null)queue.add(node.left);if(node.right!=null)queue.add(node.right);}}return deep;}
}

111.二叉树的最小深度

在这里插入图片描述

思路:

相对于 104.二叉树的最大深度 ,本题还也可以使用层序遍历的方式来解决,思路是一样的。

需要注意的是,只有当左右孩子都为空的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点

class Solution {public int minDepth(TreeNode root) {Queue<TreeNode> queue = new LinkedList<>();int deep=0;if(root!=null){queue.add(root);}while(!queue.isEmpty()){int len=queue.size();deep++;for(int i=0;i<len;i++){TreeNode node =queue.poll();if(node.left!=null)queue.add(node.left);if(node.right!=null)queue.add(node.right);if(node.left==null&&node.right==null){return deep;}}}return deep;}
}

226.翻转二叉树

在这里插入图片描述
注意只要把每一个节点的左右孩子翻转一下,就可以达到整体翻转的效果

这道题目使用前序遍历和后序遍历都可以,唯独中序遍历不方便,因为中序遍历会把某些节点的左右孩子翻转了两次!建议拿纸画一画,就理解了

那么层序遍历可以不可以呢?依然可以的!只要把每一个节点的左右孩子翻转一下的遍历方式都是可以的!

1.递归法DFS

把每一个节点的左右孩子都进行翻转
在这里插入图片描述

代码

  • 后序遍历
class Solution {public TreeNode invertTree(TreeNode root) {if(root==null){return root;}invertTree(root.left);//左invertTree(root.right);//右// 交换				   //中TreeNode temp=null;temp=root.left;root.left=root.right;root.right=temp;return root;}
}
  • 前序遍历
class Solution {public TreeNode invertTree(TreeNode root) {if(root==null){return root;}// 交换 			//中TreeNode temp=null;temp=root.left;root.left=root.right;root.right=temp;return root;invertTree(root.left);  //左invertTree(root.right); //右}
}

2.层序遍历BFS

在添加左右节点前,进行左右节点的交换。

代码:

class Solution {public TreeNode invertTree(TreeNode root) {// if(root==null){//     return root;// }Queue<TreeNode> queue=new LinkedList<>();if(root!=null){queue.add(root);}while(!queue.isEmpty()){int len = queue.size();for(int i=0;i<len;i++){TreeNode node=queue.poll();TreeNode tmp=null;// 交换tmp=node.right;node.right=node.left;node.left = tmp;// 放入左右节点if(node.left!=null){queue.add(node.left);}if(node.right!=null){queue.add(node.right);}}}return root;}
}

101. 对称二叉树

在这里插入图片描述

思路:-使用后序遍历 左右中

首先想清楚,判断对称二叉树要比较的是哪两个节点,要比较的可不是左右节点!

对于二叉树是否对称,要比较的是根节点的左子树与右子树是不是相互翻转的,理解这一点就知道了其实我们要比较的是两个树(这两个树是根节点的左右子树),所以在递归遍历的过程中,也是要同时遍历两棵树。

递归法

  1. 确定递归函数的参数和返回值

因为我们要比较的是根节点的两个子树是否是相互翻转的,进而判断这个树是不是对称树,所以要比较的是两个树,参数自然也是左子树节点和右子树节点。

返回值自然是bool类型。

代码如下:

bool compare(TreeNode* left, TreeNode* right)
  1. 确定终止条件

要比较两个节点数值相不相同,首先要把两个节点为空的情况弄清楚!否则后面比较数值的时候就会操作空指针了。

节点为空的情况有:(注意我们比较的其实不是左孩子和右孩子,所以如下我称之为左节点右节点

  • 左节点为空,右节点不为空,不对称,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, 因为我们把以上情况都排除之后,剩下的就是 左右节点都不为空,且数值相同的情况。

  1. 确定单层递归的逻辑

此时才进入单层递归的逻辑,单层递归的逻辑就是处理 左右节点都不为空,且数值相同的情况。

  • 比较二叉树外侧是否对称:传入的是左节点的左孩子,右节点的右孩子。
  • 比较内侧是否对称,传入左节点的右孩子,右节点的左孩子。
  • 如果左右都对称就返回true ,有一侧不对称就返回false 。
bool outside = compare(left->left, right->right);   // 左子树:左、 右子树:右
bool inside = compare(left->right, right->left);    // 左子树:右、 右子树:左
bool isSame = outside && inside;                    // 左子树:中、 右子树:中(逻辑处理)
return isSame;

递归代码

class Solution {public boolean isSymmetric(TreeNode root) {return Compare(root.left,root.right);}public boolean Compare(TreeNode left,TreeNode right){if(left==null&&right==null){return true;}// if(left==null&&right!=null){//     return false;// }    // if(left!=null&&right==null){//     return false;// }// if(left.val!=right.val){//     return false;// }if (left==null||right==null||left.val != right.val) {return false;}// 比较外侧boolean outside = Compare(left.left,right.right);// 比较内侧boolean inside = Compare(left.right,right.left);return outside&&inside;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

class_10:this关键字

this关键字是指向调用对象的指针 #include <iostream> #include <iostream> using namespace std;class Car{ public://成员数据string brand; //品牌int year; //年限//构造函数名与类名相同Car(string brand,int year){cout<<"构造函数中&#…

Element中的el-input-number+SpringBoot+mysql

1、编写模板 <el-form ref"form" label-width"100px"><el-form-item label"商品id&#xff1a;"><el-input v-model"id" disabled></el-input></el-form-item><el-form-item label"商品名称&a…

【Web前端开发基础】前端基础布局之百分比布局、flex布局

前端基础布局 目录 前端基础布局布局简介盒模型1. 标准盒模型2. 怪异盒模型3. 解决方案4. 代码示例 常见的布局单位百分比布局flex布局一、Flex布局是什么&#xff1f;二、基本概念三、容器属性flex-direction属性&#xff1a;决定主轴的方向&#xff08;即项目的排列方向&…

【数据结构】链表(单链表与双链表实现+原理+源码)

博主介绍&#xff1a;✌全网粉丝喜爱、前后端领域优质创作者、本质互联网精神、坚持优质作品共享、掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战✌有需要可以联系作者我哦&#xff01; &#x1f345;附上相关C语言版源码讲解&#x1f345; &#x1f44…

开始学习Vue2(组件的生命周期和数据共享)

一、组件的生命周期 1. 生命周期 & 生命周期函数 生命周期&#xff08;Life Cycle&#xff09;是指一个组件从创建 -> 运行 -> 销毁的整个阶段&#xff0c;强调的是一个时间段。 生命周期函数&#xff1a;是由 vue 框架提供的内置函数&#xff0c;会伴随着 组件…

2024/1/24HTML学习:路径

路径 3.2.1路径的介绍 加载图片&#xff0c;需要找到对应的图片。 通过一定的路径 路径分两种 绝对路径&#xff08;了解&#xff09;相对路径&#xff08;常用&#xff09; 绝对路径&#xff1a;绝对位置&#xff0c;从盘符开始的路径 1.盘符开头D:\....................…

java开发——《并发编程》

目录 一.jmm 二.并发了什么 1.只有一个核&#xff08;单核&#xff09;并发还有没有意义 2.单核&#xff0c;还有什么可见性问题 3.并发和并行 三.volitaile 1.变量的可见性问题 2.原因是什么 3.本次修改的变量直接刷到主内存 4.声明其他内存对于这个地址的缓存无效 …

Addressables(2) ResourceLocation和AssetReference

IResourceLocation var op Addressables.LoadResourceLocationsAsync(key); var result op.WaitForCompletion(); 把加载的Key塞进去&#xff0c;不难看出&#xff0c;IResourceLocation可以用来获得资源的详细信息 很适合用于更新分析&#xff0c;或者一些检查工具 AssetR…

RabbitMQ中交换机的应用及原理,案例的实现

目录 一、介绍 1. 概述 2. 作用及优势 3. 工作原理 二、交换机Exchange 1. Direct 2. Topic 3. Fanout 三、代码案例 消费者代码 1. 直连direct 生产者代码 测试 2. 主题topic 生产者代码 测试 3. 扇形fanout 生产者代码 测试 每篇一获 一、介绍 1. …

MySQL定期整理磁盘碎片

MySQL定期整理磁盘碎片&#xff1a;提升数据库性能的终极指南 MySQL作为一个强大的关系型数据库管理系统&#xff0c;在长时间运行后可能会产生磁盘碎片&#xff0c;影响数据库性能。本博客将深入讨论如何定期整理MySQL磁盘碎片&#xff0c;以确保数据库的高效运行。我们将介绍…

【心得】java从CC1链入门CC链个人笔记

来劲了&#xff0c;感觉离真正的CTF又近了一步。 本文仅从一个萌新的角度去谈&#xff0c;如有纰漏&#xff0c;纯属蒟蒻。 目录 CC链概念 CC链学习前置知识 CC1链 Version1 Version2 Version3 CC链概念 CC链 Commons Collections apache组织发布的开源库 里面主要对…

计算机网络-物理层基本概念(接口特性 相关概念)

文章目录 总览物理层接口特性星火模型给出的相关概念解释&#xff08;仅供参考&#xff09; 总览 求极限传输速率&#xff1a;奈氏准则&#xff0c;香农定理&#xff08;背景环境不一样&#xff09; 编码&#xff1a;数据变成数字信号 调制&#xff1a;数字信号变成模拟信号 信…

AMIS的组件学习使用

部分代码片段 {"id": "filterForm","className": " xysd-zbkb-pubquery","labelWidth": 130,"body": [{"type": "grid","className": "xysd-grid-query-input","c…

(二)MySQL安装与部署(redhat9)

前言 MySQL仅仅是一个产品&#xff0c;Oracle旗下的小型数据库。广泛应用在中小型项目中&#xff0c;特征体积小速度快整体成本低。尤其是开源&#xff0c;所以很多中小型项目为了降低成本纷纷选用MySql作为数控存储介质 MySql的特征 底层语言使用C、C编写的。并且使用多种编…

常用芯片学习——MBI5020芯片

MBI5020 16位恒流LED驱动器 使用说明 MBI5020内建一个16位位移寄存器(Shift Register)及一个16位输出缓存器&#xff0c;可将串行式输入数据转换为并列式输出格式。在输出端&#xff0c;设计16个稳定的电流源&#xff0c;可以因应LED负载电压 (VF) 的变化&#xff0c;提供均匀…

GoZero的一个注意点,goctl生成代码不会处理时间字段

起因 进行一个功能的编写时发现goctl生成的代码在insert时候不把时间给赋值进去 于是懵逼开始寻找原因 探究 再查看发现 goctl在对xxxExpectAutoSet和RowsWithPlaceHolder赋值时候就去掉了所有跟时间相关的信息字段 于是去查看官方文档&#xff0c;依稀记得官方提供了示例…

20240122在WIN10+GTX1080下使用字幕小工具V1.2的使用总结(whisper)

20240122在WIN10GTX1080下使用字幕小工具V1.2的使用总结 2024/1/22 19:52 结论&#xff1a;这个软件如果是习作&#xff0c;可以打101分&#xff0c;功能都实现了。 如果作为商业软件/共享软件&#xff0c;在易用性等方面&#xff0c;可能就只能有70分了。 【百分制】 可选的改…

【MySQL】打开科技创新的第一生产力

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-EtRkflNU19AGWAkT {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

【Java程序员面试专栏 专业技能篇】计算机网络核心面试指引

关于计算机网络部分的核心知识进行一网打尽,包括计算机的网络模型,各个层的一些重点概念,通过一篇文章串联面试重点,并且帮助加强日常基础知识的理解,全局思维导图如下所示 分层基本概念 计算机网络模型的分层及具体作用 计算机网络有哪些分层模型 可以按照应用层到物…