-
Notifications
You must be signed in to change notification settings - Fork 43
/
SumOfLeftLeaves.java
218 lines (181 loc) · 6.58 KB
/
SumOfLeftLeaves.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
package LeetCodeJava.Recursion;
// https://leetcode.com/problems/sum-of-left-leaves/
import LeetCodeJava.DataStructure.TreeNode;
import java.util.ArrayDeque;
import java.util.Deque;
public class SumOfLeftLeaves {
// VO
// IDEA: DFS (post order traverse)
int res = 0;
public int sumOfLeftLeaves(TreeNode root) {
if (root == null){
return this.res;
}
if (root.left == null && root.right == null){
return this.res;
}
// helper
//this._help(root, false, 0);
this._help(root, false);
return this.res;
}
private void _help(TreeNode root, boolean isLeft){
// post traverse
if (root == null){
return;
}
_help(root.left, true);
_help(root.right, false);
if (root.left == null && root.right == null){
if(isLeft){
//System.out.println(">>> lastval = " + lastVal);
/** NOTE !!! we add cur root val here, instead of last val */
this.res += root.val;
}
}
}
// V0'
// IDEA : BFS (Pre-order)
private boolean isLeaf(TreeNode node) {
return node != null && node.left == null && node.right == null;
}
public int sumOfLeftLeaves_0_1(TreeNode root) {
if (root == null) {
return 0;
}
int total = 0;
Deque<TreeNode> stack = new ArrayDeque<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode subRoot = stack.pop();
// Check if the left node is a leaf node.
if (isLeaf(subRoot.left)) {
total += subRoot.left.val;
}
// If the right node exists, put it on the stack.
if (subRoot.right != null) {
stack.push(subRoot.right);
}
// If the left node exists, put it on the stack.
if (subRoot.left != null) {
stack.push(subRoot.left);
}
}
return total;
}
// V1
// IDEA : Iterative Tree Traversal (Pre-order)
// https://leetcode.com/problems/sum-of-left-leaves/editorial/
private boolean isLeaf_1(TreeNode node) {
return node != null && node.left == null && node.right == null;
}
public int sumOfLeftLeaves_1(TreeNode root) {
if (root == null) {
return 0;
}
int total = 0;
Deque<TreeNode> stack = new ArrayDeque<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode subRoot = stack.pop();
// Check if the left node is a leaf node.
if (isLeaf_1(subRoot.left)) {
total += subRoot.left.val;
}
// If the right node exists, put it on the stack.
if (subRoot.right != null) {
stack.push(subRoot.right);
}
// If the left node exists, put it on the stack.
if (subRoot.left != null) {
stack.push(subRoot.left);
}
}
return total;
}
// V2
// IDEA : Recursive Tree Traversal (Pre-order)
// https://leetcode.com/problems/sum-of-left-leaves/editorial/
public int sumOfLeftLeaves_2(TreeNode root) {
if (root == null) {
return 0;
}
return processSubtree(root, false);
}
private int processSubtree(TreeNode subtree, boolean isLeft) {
// Base case: This is a leaf node.
if (subtree.left == null && subtree.right == null) {
return isLeft ? subtree.val : 0;
}
// Recursive case: We need to add and return the results of the
// left and right subtrees.
int total = 0;
if (subtree.left != null) {
total += processSubtree(subtree.left, true);
}
if (subtree.right != null) {
total += processSubtree(subtree.right, false);
}
return total;
}
// V2-1
// IDEA : Recursive Tree Traversal (Pre-order) simplified
// https://leetcode.com/problems/sum-of-left-leaves/editorial/
public int sumOfLeftLeaves_2_1(TreeNode root) {
return processSubtree_2_1(root, false);
}
private int processSubtree_2_1(TreeNode subtree, boolean isLeft) {
// Base case: This is an empty subtree.
if (subtree == null) {
return 0;
}
// Base case: This is a leaf node.
if (subtree.left == null && subtree.right == null) {
return isLeft ? subtree.val : 0;
}
// Recursive case: We need to add and return the results of the
// left and right subtrees.
return processSubtree_2_1(subtree.left, true) + processSubtree_2_1(subtree.right, false);
}
// V3
// IDEA : Morris Tree Traversal (Pre-order)
// https://leetcode.com/problems/sum-of-left-leaves/editorial/
public int sumOfLeftLeaves_3(TreeNode root) {
int totalSum = 0;
TreeNode currentNode = root;
while (currentNode != null) {
// If there is no left child, we can simply explore the right subtree
// without needing to worry about keeping track of currentNode's other
// child.
if (currentNode.left == null) {
currentNode = currentNode.right;
} else {
TreeNode previous = currentNode.left;
// Check if this left node is a leaf node.
if (previous.left == null && previous.right == null) {
totalSum += previous.val;
}
// Find the inorder predecessor for currentNode.
while (previous.right != null && !previous.right.equals(currentNode)) {
previous = previous.right;
}
// We've not yet visited the inorder predecessor. This means that we
// still need to explore currentNode's left subtree. Before doing this,
// we will put a link back so that we can get back to the right subtree
// when we need to.
if (previous.right == null) {
previous.right = currentNode;
currentNode = currentNode.left;
}
// We have already visited the inorder predecessor. This means that we
// need to remove the link we added, and then move onto the right
// subtree and explore it.
else {
previous.right = null;
currentNode = currentNode.right;
}
}
}
return totalSum;
}
}