-
Notifications
You must be signed in to change notification settings - Fork 21
/
114. Flatten Binary Tree to Linked List.java
executable file
·156 lines (130 loc) · 4.03 KB
/
114. Flatten Binary Tree to Linked List.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
M
tags: Binary Tree, DFS
time: O(n)
space: O(n), stacks
给一个binary tree, 把tree做成 linked list的形式, in-place.
#### Method1: DFS return tail node
- DFS to return the tail of the flattened list
- Careful handling the null child. Choose one and both works:
- Option1: put non-null as right child and continue dfs
- Option2: put non-null as left child and continue dfs
#### Method2: void DFS
- latten the tree, no extra space.
- 1. Set right node in buffer, and connect: `root.right = root.left`, DFS flatten(root.right)
- 3. 移花接木: traverse to tail of the current root.right and attach the buffer node.
- 3. flatten the remaining of buffer
##### 注意
- 顺序一定要清楚, 不能写错, 写几个example可以看出来
- 移动的那些node, 要把node.left = null, 清扫干净
```
/*
Given a binary tree, flatten it to a linked list in-place.
For example,
Given
1
/ \
2 5
/ \ \
3 4 6
The flattened tree should look like:
1
\
2
\
3
\
4
\
5
\
6
click to show hints.
Hints:
If you notice carefully in the flattened tree, each node's right child points to
the next node of a pre-order traversal.
Challenge
Do it in-place without any extra memory.
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
// Method1, Option1: DFS by returning and attaching tail, move non-null child to right side
class Solution {
public void flatten(TreeNode root) {
if (root == null) return;
dfs(root);
}
public TreeNode dfs(TreeNode node) {
if (node.left == null && node.right == null) return node;
if (node.right == null) { // when one of them is null, attach remaining to right side
node.right = node.left;
node.left = null;
}
TreeNode temp = node.right; // buffer
if (node.left != null) { // DFS to find tail, and attach right to tail
TreeNode tail = dfs(node.left);
node.right = node.left;
node.left = null;
tail.right = temp;
}
// DFS the rest right
return dfs(temp);
}
}
// Method1, Option2: DFS by returning and attaching tail, move non-null child to left
class Solution {
public void flatten(TreeNode root) {
if (root == null) return;
dfs(root);
}
public TreeNode dfs(TreeNode node) {
if (node.left == null && node.right == null) return node;
if (node.left == null) { // node.right != null, then swich right to left, so the logic below can work
node.left = node.right;
node.right = null;
}
TreeNode temp = node.right;
TreeNode tail = dfs(node.left);
node.right = node.left;
node.left = null;
if (temp == null) return tail; // do not test null right
tail.right = temp;
return dfs(temp);
}
}
/*
Method2:
1. Move root.left to root.rigthMost child (while loop find leaf)
2. Take notion of the first root.right, and flatten(xx) on it.
3. On each level, if not left child, flatten right child.
*/
class Solution {
public void flatten(TreeNode root) {
if (root == null) return;
if (root.left == null) {
flatten(root.right);
} else {
// Reserve right sub tree
TreeNode rightNode = root.right;
// Move left child to right side, cut off original left child
root.right = root.left;
root.left = null;
// Flatten the new right child
flatten(root.right);
// Append previous right child to end of flatten tree
TreeNode node = root;
while (node.right != null) {
node = node.right;
}
node.right = rightNode; // connect
flatten(root.right);
}
}
}
```