LeetCode 662. Maximum Width of Binary Tree
662. Maximum Width of Binary Tree
Given a binary tree, write a function to get the maximum width of the given tree. The width of a tree is the maximum width among all levels. The binary tree has the same structure as a full binary tree, but some nodes are null.
The width of one level is defined as the length between the end-nodes (the leftmost and right most non-null nodes in the level, where the null
nodes between the end-nodes are also counted into the length calculation.
Example 1:
Input:
1
/
3 2
/
5 3 9
Output: 4
Explanation: The maximum width existing in the third level with the length 4 (5,3,null,9).
Example 2:
Input:
1
/
3
/
5 3
Output: 2
Explanation: The maximum width existing in the third level with the length 2 (5,3).
Example 3:
Input:
1
/
3 2
/
5
Output: 2
Explanation: The maximum width existing in the second level with the length 2 (3,2).
Example 4:
Input:
1
/
3 2
/
5 9
/
6 7
Output: 8
Explanation:The maximum width existing in the fourth level with the length 8 (6,null,null,null,null,null,null,7).
题目大意:求二叉树的宽度。
思路:二叉数的DFS,对二叉树的节点进行标号,若某节点的标号为m,那么左右孩子的标号为2*m、2*m+1。
解法一:
带返回值的
public int widthOfBinaryTree(TreeNode root) {
List<Integer> lefts = new ArrayList<>();
return dfs(root,1,0,lefts);
}
public int dfs(TreeNode root,int id,int depth,List<Integer> lefts){
if (root == null ) return 0;
if ( depth>=lefts.size()) lefts.add(id);
return Math.max(id-lefts.get(depth)+1,Math.max(dfs(root.left,2*id,depth+1,lefts),dfs(root.right,2*id+1,depth+1,lefts)));
}
lefts记录的是最左节点的标号(id),每一个节点的id与最左节点的id相间就是宽度,取最大值就是结果。
解法二:
不带返回值的
错误解法:
public int widthOfBinaryTree(TreeNode root) {
List<Integer> lefts = new ArrayList<>();
Integer res = new Integer(0);
dfs(root,1,0,lefts,res);
return res;
}
public void dfs(TreeNode root,int id,int depth,List<Integer> lefts,Integer res ){
if (root ==null) return;
if (depth>=lefts.size()) lefts.add(id);
res = Math.max(res,id+1-lefts.get(depth));
dfs(root.left,id*2,depth+1,lefts,res);
dfs(root.right,id*2+1,depth+1,lefts,res);
}
Java中,String类型和包装类型作为参数传递时,是属于值传递还是引用传递呢?
下面我们来看一个例子:
public class Test {
public static void test1(Integer num){
num = new Integer(5);
}
public static void test2(String str){
str.replace("1", "4");
}
public static void main(String[] args) {
Integer num = new Integer(1);
test1(num);
// 输出结果为1
System.out.println(num.intValue());
String str = new String("123");
test2(str);
// 输出结果为123
System.out.println(str);
}
}
上述程序很容易让人误以为String类型和包装类型是值传递。 其实我们认真想一下: String类型和包装类型都是对象类型,所以必然是引用传递;
但是由于String类和包装类都没有提供value对应的setter方法,我们无法改变其内容,所以导致我们看起来好像是值传递。所以说,String类和包装类是一种的特殊的引用传递。需要注意的是,这类特殊的引用传递不像普通的引用传递一样操作地址可以修改其值,因此上述的错误解法需要引起我们的注意。
那么我们也可以采用数组的方式作为参数,这样可以方便的解决。
正确的解法:
public int widthOfBinaryTree(TreeNode root) {
List<Integer> lefts = new ArrayList<>();
int[] res= new int[1];
dfs(root,1,0,lefts,res);
return res[0];
}
public void dfs(TreeNode root,int id,int depth,List<Integer> lefts,int[] res ){
if (root ==null) return;
if (depth>=lefts.size()) lefts.add(id);
res[0] = Math.max(res[0],id+1-lefts.get(depth));
dfs(root.left,id*2,depth+1,lefts,res);
dfs(root.right,id*2+1,depth+1,lefts,res);
}
其实我们还可以将res设置为全局变量,这样少一个参数,但是往往我们设计程序的原则是少用全局变量。
总结,对二叉树的宽度问题求解时候,对节点进行编号往往可以达到事半功倍的效果。
- 版本管理工具总结
- java枚举类型enum的使用
- (66) 理解synchronized / 计算机程序的思维逻辑
- 用Python搭建一个校园维基网站(一)
- (67) 线程的基本协作机制 (上) / 计算机程序的思维逻辑
- 制作Aspose CHM文档的过程记录
- 用python搭建一个校园维基网站(二)—— 可编辑内容的首页的创建
- Django博客教程(四):让 django 完成翻译—迁移数据库模型
- Calendar类中add/set/roll方法的区别
- 如何构建一个分布式爬虫(理论篇)
- Python微型Web框架Bottle源码分析
- VirtualBox相关问题总结
- Java 枚举7常见种用法
- ALI的Tensorflow炼成与GAN科普
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 面试官问我Volatile的原理?从操作系统层面的设计怼回去!
- 设计原则之单一职责
- 设计原则之开闭原则
- SpringBoot执行跨域处理
- SpringBoot对全局异常的处理封装
- 自定义springboot-starter揭秘自动配置骚操作
- 【大厂面试题】Redis中是如何实现分布式锁的?
- 最近公司招人,研发组商量了下,暂时定下这么多java面试题!
- 市面上数据库种类那么多,如何选择?
- 玩转正则!推荐一个速查、调试、验证、可视化工具
- 当一个http请求来临时,SpringMVC究竟偷偷帮你做了什么?
- Js实现文本复制
- 当一个http请求来临时,SpringMVC究竟偷偷帮你做了什么?处理器映射器与处理器篇
- anetTcpGenericConnect 详解
- 详解 MySQL 基准测试和sysbench工具