Skip to content

Commit 23dcdac

Browse files
committed
rafactor: isBalanced tree
1 parent 03fb983 commit 23dcdac

File tree

1 file changed

+45
-103
lines changed

1 file changed

+45
-103
lines changed

08-二叉树递归解题思路.md

Lines changed: 45 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
[TOC]
2-
# 1 二叉树的递归套路
2+
# 1 二叉树的递归解法
33

44
1、 可以解决面试中的绝大部分二叉树(95%以上)的问题,尤其是树形dp问题
55

66
2、 其本质是利用递归遍历二叉树的便利性,每个节点在递归的过程中可以回到该节点3次
77

88

9-
==具体步骤为:==
10-
9+
具体步骤为:
1110
1. 假设以X节点为头,假设可以向X左树和右树要任何信息
1211
2. 在上一步的假设下,讨论以X为头结点的树,得到答案的可能性(最重要),常见分类是与X无关的答案,与X有关的答案
1312
3. 列出所有可能性后,确定到底需要向左树和右树要什么样的信息
1413
4. 把左树信息和右树信息求全集,就是任何一颗子树都需要返回的信息S
1514
5. 递归函数都返回S,每颗子树都这么要求
1615
6. 写代码,在代码中考虑如何把左树信息和右树信息整合出整棵树的信息
1716

18-
## 1.1 二叉树的递归套路深度实践
17+
## 1.1 二叉树的递归解法实操
1918

2019
### 1.1.1 例一:判断二叉树平衡与否
2120

@@ -27,112 +26,55 @@
2726
2827
> 所以该题,我们X需要向左右子树要的信息为,1.高度 2. 是否平衡
2928
30-
```Java
31-
package class08;
32-
33-
public class Code01_IsBalanced {
34-
35-
public static class Node {
36-
public int value;
37-
public Node left;
38-
public Node right;
39-
40-
public Node(int data) {
41-
this.value = data;
42-
}
43-
}
44-
45-
public static boolean isBalanced1(Node head) {
46-
boolean[] ans = new boolean[1];
47-
ans[0] = true;
48-
process1(head, ans);
49-
return ans[0];
50-
}
51-
52-
public static int process1(Node head, boolean[] ans) {
53-
if (!ans[0] || head == null) {
54-
return -1;
55-
}
56-
int leftHeight = process1(head.left, ans);
57-
int rightHeight = process1(head.right, ans);
58-
if (Math.abs(leftHeight - rightHeight) > 1) {
59-
ans[0] = false;
60-
}
61-
return Math.max(leftHeight, rightHeight) + 1;
62-
}
63-
64-
public static boolean isBalanced2(Node head) {
65-
return process2(head).isBalaced;
66-
}
67-
68-
// 左、右要求一样,Info 表示信息返回的结构体
69-
public static class Info {
70-
// 是否平衡
71-
public boolean isBalaced;
72-
// 高度多少
73-
public int height;
29+
```Go
30+
package main
7431

75-
public Info(boolean b, int h) {
76-
isBalaced = b;
77-
height = h;
78-
}
79-
}
32+
import "math"
8033

81-
// 递归调用,X自身也要返回信息Info。
82-
// 解决X节点(当前节点)怎么返回Info信息
83-
public static Info process2(Node X) {
84-
// base case
85-
if (X == null) {
86-
return new Info(true, 0);
87-
}
88-
// 得到左树信息
89-
Info leftInfo = process2(X.left);
90-
// 得到右树信息
91-
Info rightInfo = process2(X.right);
92-
93-
// 高度等于左右最大高度,加上当前头结点的高度1
94-
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
95-
boolean isBalanced = true;
96-
// 左树不平衡或者右树不平衡,或者左右两子树高度差超过1
97-
// 那么当前节点为头的树,不平衡
98-
if (!leftInfo.isBalaced || !rightInfo.isBalaced || Math.abs(leftInfo.height - rightInfo.height) > 1) {
99-
isBalanced = false;
100-
}
101-
// 加工出当前节点的信息返回
102-
return new Info(isBalanced, height);
103-
}
34+
type Node struct {
35+
Val int
36+
Left *Node
37+
Right *Node
38+
}
10439

105-
// for test
106-
public static Node generateRandomBST(int maxLevel, int maxValue) {
107-
return generate(1, maxLevel, maxValue);
108-
}
40+
// BalanceInfo 表示递归过程中需要收集每个节点的信息
41+
type BalanceInfo struct {
42+
// 当前节点为头的树是不是平衡的
43+
IsBalanced bool
44+
// 当前节点为头的树的高度是多少
45+
Height int
46+
}
10947

110-
// for test
111-
public static Node generate(int level, int maxLevel, int maxValue) {
112-
if (level > maxLevel || Math.random() < 0.5) {
113-
return null;
114-
}
115-
Node head = new Node((int) (Math.random() * maxValue));
116-
head.left = generate(level + 1, maxLevel, maxValue);
117-
head.right = generate(level + 1, maxLevel, maxValue);
118-
return head;
119-
}
48+
// IsBalanced 给定二叉树头节点,判断该二叉树是不是平衡二叉树
49+
func (head *Node) IsBalanced() bool {
50+
return Process(head).IsBalanced
51+
}
12052

121-
public static void main(String[] args) {
122-
int maxLevel = 5;
123-
int maxValue = 100;
124-
int testTimes = 1000000;
125-
for (int i = 0; i < testTimes; i++) {
126-
Node head = generateRandomBST(maxLevel, maxValue);
127-
if (isBalanced1(head) != isBalanced2(head)) {
128-
System.out.println("Oops!");
129-
}
130-
}
131-
System.out.println("finish!");
53+
func Process(node *Node) *BalanceInfo {
54+
if node == nil {
55+
return &BalanceInfo{
56+
IsBalanced: true,
57+
Height: 0,
58+
}
59+
}
60+
// 左子树信息
61+
leftInfo := Process(node.Left)
62+
// 右子树信息
63+
rightInfo := Process(node.Right)
64+
// 高度等于左右最大高度,加上当前头结点的高度1
65+
curHeight := int(math.Max(float64(leftInfo.Height), float64(rightInfo.Height))) + 1
66+
curIsBalanced := true
67+
// 左树不平衡或者右树不平衡,或者左右两子树高度差超过1
68+
// 那么当前节点为头的树,不平衡
69+
if !leftInfo.IsBalanced || !rightInfo.IsBalanced || math.Abs(float64(leftInfo.Height) -float64(rightInfo.Height)) > 1 {
70+
curIsBalanced = false
71+
}
72+
// 加工出当前节点的信息返回
73+
return &BalanceInfo{
74+
IsBalanced: curIsBalanced,
75+
Height: curHeight,
13276
}
133-
13477
}
135-
13678
```
13779

13880
### .1.2 例二:返回二叉树任意两个节点最大值

0 commit comments

Comments
 (0)