1
+ // 662. 二叉树最大宽度
2
+
3
+
4
+ /**
5
+ * Definition for a binary tree node.
6
+ * public class TreeNode {
7
+ * int val;
8
+ * TreeNode left;
9
+ * TreeNode right;
10
+ * TreeNode() {}
11
+ * TreeNode(int val) { this.val = val; }
12
+ * TreeNode(int val, TreeNode left, TreeNode right) {
13
+ * this.val = val;
14
+ * this.left = left;
15
+ * this.right = right;
16
+ * }
17
+ * }
18
+ */
19
+
20
+
21
+ /*
22
+ 递归:
23
+ 1、成员变量最大宽度maxWidth,哈希表map保存每层第一个节点的位置值 {深度:位置}
24
+ 2、定义递归函数:
25
+ 1)方法功能:入参是节点、深度、位置,从map中获取同深度即同层的第一个节点位置,更新计算最大宽度
26
+ 2)终止条件:节点为空时,结束
27
+ 3)递归逻辑:左右节点同样需要计算其所在层的宽度,因此调用同样的方法递归处理
28
+ */
29
+ class Solution {
30
+ private int maxWidth = 0 ;
31
+ private Map <Integer , Integer > map = new HashMap <>();
32
+
33
+ public int widthOfBinaryTree (TreeNode root ) {
34
+ dfs (root , 0 , 0 );
35
+ return maxWidth ;
36
+ }
37
+
38
+ private void dfs (TreeNode root , int depth , int pos ) {
39
+ if (root == null ) {
40
+ return ;
41
+ }
42
+ map .computeIfAbsent (depth , key -> pos );
43
+ maxWidth = Math .max (maxWidth , pos - map .get (depth ) + 1 );
44
+ dfs (root .left , depth + 1 , 2 * pos );
45
+ dfs (root .right , depth + 1 , 2 * pos + 1 );
46
+ }
47
+ }
48
+
49
+
50
+ /*
51
+ 迭代:
52
+ 1、节点为空时返回0
53
+ 2、使用两个队列,节点队列nodeQueue存放节点,位置队列posQueue存放节点的位置值,初始化时加入根节点和位置值到队列中
54
+ 3、位置关系:根节点位置为 i,则左节点位置为 2i,有节点位置为 2i+1
55
+ 4、层序遍历,记录当前层最左边的位置,遍历更新右边的位置,计算更新当前层宽度,并把下一层的节点和位置值存入队列
56
+ 5、每层遍历完后都更新最大宽度,最终得到二叉树的最大宽度
57
+
58
+ 1
59
+ / \
60
+ 2 3
61
+ */
62
+ class Solution {
63
+ public int widthOfBinaryTree (TreeNode root ) {
64
+ if (root == null ) {
65
+ return 0 ;
66
+ }
67
+ Queue <TreeNode > nodeQueue = new LinkedList <>();
68
+ Queue <Integer > posQueue = new LinkedList <>();
69
+ nodeQueue .add (root );
70
+ posQueue .add (1 );
71
+ int maxWidth = 0 ;
72
+ while (!nodeQueue .isEmpty ()) {
73
+ boolean firstFlag = true ;
74
+ int left = -1 , right = -1 , tempWidth = 0 ;
75
+ int size = nodeQueue .size ();
76
+ while (size > 0 ) {
77
+ TreeNode node = nodeQueue .poll ();
78
+ int pos = posQueue .poll ();
79
+ if (firstFlag ) {
80
+ left = pos ;
81
+ firstFlag = false ;
82
+ }
83
+ right = pos ;
84
+ tempWidth = Math .max (tempWidth , right - left + 1 );
85
+ if (node .left != null ) {
86
+ nodeQueue .add (node .left );
87
+ posQueue .add (2 * pos );
88
+ }
89
+ if (node .right != null ) {
90
+ nodeQueue .add (node .right );
91
+ posQueue .add (2 * pos + 1 );
92
+ }
93
+ size --;
94
+ }
95
+ maxWidth = Math .max (maxWidth , tempWidth );
96
+ }
97
+ return maxWidth ;
98
+ }
99
+ }
100
+
101
+
102
+ /*
103
+ 迭代优化:位置队列posQueue存放的是一层节点的所有位置,直接取最左边和最右边的位置就可以计算当前层的宽度,再更新最大宽度
104
+ */
105
+ class Solution {
106
+ public int widthOfBinaryTree (TreeNode root ) {
107
+ if (root == null ) {
108
+ return 0 ;
109
+ }
110
+ LinkedList <TreeNode > nodeQueue = new LinkedList <>();
111
+ LinkedList <Integer > posQueue = new LinkedList <>();
112
+ nodeQueue .add (root );
113
+ posQueue .add (1 );
114
+ int maxWidth = 0 ;
115
+ while (!nodeQueue .isEmpty ()) {
116
+ maxWidth = Math .max (maxWidth , posQueue .peekLast () - posQueue .peekFirst () + 1 );
117
+ int size = nodeQueue .size ();
118
+ while (size > 0 ) {
119
+ TreeNode node = nodeQueue .poll ();
120
+ int pos = posQueue .poll ();
121
+ if (node .left != null ) {
122
+ nodeQueue .add (node .left );
123
+ posQueue .add (2 * pos );
124
+ }
125
+ if (node .right != null ) {
126
+ nodeQueue .add (node .right );
127
+ posQueue .add (2 * pos + 1 );
128
+ }
129
+ size --;
130
+ }
131
+ }
132
+ return maxWidth ;
133
+ }
134
+ }
0 commit comments