|
1 | 1 | [TOC]
|
2 |
| -# 1 二叉树的递归套路 |
| 2 | +# 1 二叉树的递归解法 |
3 | 3 |
|
4 | 4 | 1、 可以解决面试中的绝大部分二叉树(95%以上)的问题,尤其是树形dp问题
|
5 | 5 |
|
6 | 6 | 2、 其本质是利用递归遍历二叉树的便利性,每个节点在递归的过程中可以回到该节点3次
|
7 | 7 |
|
8 | 8 |
|
9 |
| -==具体步骤为:== |
10 |
| - |
| 9 | +具体步骤为: |
11 | 10 | 1. 假设以X节点为头,假设可以向X左树和右树要任何信息
|
12 | 11 | 2. 在上一步的假设下,讨论以X为头结点的树,得到答案的可能性(最重要),常见分类是与X无关的答案,与X有关的答案
|
13 | 12 | 3. 列出所有可能性后,确定到底需要向左树和右树要什么样的信息
|
14 | 13 | 4. 把左树信息和右树信息求全集,就是任何一颗子树都需要返回的信息S
|
15 | 14 | 5. 递归函数都返回S,每颗子树都这么要求
|
16 | 15 | 6. 写代码,在代码中考虑如何把左树信息和右树信息整合出整棵树的信息
|
17 | 16 |
|
18 |
| -## 1.1 二叉树的递归套路深度实践 |
| 17 | +## 1.1 二叉树的递归解法实操 |
19 | 18 |
|
20 | 19 | ### 1.1.1 例一:判断二叉树平衡与否
|
21 | 20 |
|
|
27 | 26 |
|
28 | 27 | > 所以该题,我们X需要向左右子树要的信息为,1.高度 2. 是否平衡
|
29 | 28 |
|
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 |
74 | 31 |
|
75 |
| - public Info(boolean b, int h) { |
76 |
| - isBalaced = b; |
77 |
| - height = h; |
78 |
| - } |
79 |
| - } |
| 32 | +import "math" |
80 | 33 |
|
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 | +} |
104 | 39 |
|
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 | +} |
109 | 47 |
|
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 | +} |
120 | 52 |
|
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, |
132 | 76 | }
|
133 |
| - |
134 | 77 | }
|
135 |
| - |
136 | 78 | ```
|
137 | 79 |
|
138 | 80 | ### .1.2 例二:返回二叉树任意两个节点最大值
|
|
0 commit comments