Skip to content

Commit c230bd0

Browse files
add maximum-average-subtree.md article
1 parent 99c033a commit c230bd0

File tree

1 file changed

+175
-0
lines changed

1 file changed

+175
-0
lines changed
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
## 1. Postorder Traversal
2+
3+
::tabs-start
4+
5+
```python
6+
class Solution:
7+
# for each node in the tree, we will maintain three values
8+
class State:
9+
def __init__(self, nodes, sum_val, max_average):
10+
# count of nodes in the subtree
11+
self.node_count = nodes
12+
# sum of values in the subtree
13+
self.value_sum = sum_val
14+
# max average found in the subtree
15+
self.max_average = max_average
16+
17+
def maximumAverageSubtree(self, root: Optional[TreeNode]) -> float:
18+
return self.max_average(root).max_average
19+
20+
def max_average(self, root):
21+
if root is None:
22+
return self.State(0, 0, 0)
23+
24+
# postorder traversal, solve for both child nodes first.
25+
left = self.max_average(root.left)
26+
right = self.max_average(root.right)
27+
28+
# now find nodeCount, valueSum and maxAverage for current node `root`
29+
node_count = left.node_count + right.node_count + 1
30+
sum_val = left.value_sum + right.value_sum + root.val
31+
max_average = max(
32+
(1.0 * sum_val) / node_count, # average for current node
33+
max(right.max_average, left.max_average) # max average from child nodes
34+
)
35+
36+
return self.State(node_count, sum_val, max_average)
37+
```
38+
39+
```java
40+
class Solution {
41+
// for each node in the tree, we will maintain three values
42+
class State {
43+
// count of nodes in the subtree
44+
int nodeCount;
45+
46+
// sum of values in the subtree
47+
int valueSum;
48+
49+
// max average found in the subtree
50+
double maxAverage;
51+
52+
State(int nodes, int sum, double maxAverage) {
53+
this.nodeCount = nodes;
54+
this.valueSum = sum;
55+
this.maxAverage = maxAverage;
56+
}
57+
}
58+
59+
public double maximumAverageSubtree(TreeNode root) {
60+
return maxAverage(root).maxAverage;
61+
}
62+
63+
State maxAverage(TreeNode root) {
64+
if (root == null) {
65+
return new State(0, 0, 0);
66+
}
67+
68+
// postorder traversal, solve for both child nodes first.
69+
State left = maxAverage(root.left);
70+
State right = maxAverage(root.right);
71+
72+
// now find nodeCount, valueSum and maxAverage for current node `root`
73+
int nodeCount = left.nodeCount + right.nodeCount + 1;
74+
int sum = left.valueSum + right.valueSum + root.val;
75+
double maxAverage = Math.max(
76+
(1.0 * (sum)) / nodeCount, // average for current node
77+
Math.max(right.maxAverage, left.maxAverage) // max average from child nodes
78+
);
79+
80+
return new State(nodeCount, sum, maxAverage);
81+
}
82+
}
83+
```
84+
85+
```cpp
86+
class Solution {
87+
public:
88+
double maximumAverageSubtree(TreeNode* root) {
89+
return maxAverage(root).maxAverage;
90+
}
91+
92+
private:
93+
struct State {
94+
// count of nodes in the subtree
95+
int nodeCount;
96+
97+
// sum of values in the subtree
98+
int valueSum;
99+
100+
// max average found in the subtree
101+
double maxAverage;
102+
};
103+
104+
State maxAverage(TreeNode* root) {
105+
if (!root) return {0, 0, 0};
106+
107+
// postorder traversal, solve for both child nodes first.
108+
State left = maxAverage(root->left);
109+
State right = maxAverage(root->right);
110+
111+
// now find nodeCount, valueSum and maxAverage for current node `root`
112+
int nodeCount = left.nodeCount + right.nodeCount + 1;
113+
int sum = left.valueSum + right.valueSum + root->val;
114+
double maxAverage = max(
115+
(1.0 * (sum)) / nodeCount, // average for current node
116+
max(right.maxAverage, left.maxAverage) // max average from child nodes
117+
);
118+
119+
return {nodeCount, sum, maxAverage};
120+
}
121+
};
122+
```
123+
124+
```javascript
125+
// for each node in the tree, we will maintain three values
126+
class State {
127+
constructor(nodes, sum, maxAverage) {
128+
// count of nodes in the subtree
129+
this.nodeCount = nodes;
130+
// sum of values in the subtree
131+
this.valueSum = sum;
132+
// max average found in the subtree
133+
this.maxAverage = maxAverage;
134+
}
135+
}
136+
137+
class Solution {
138+
/**
139+
* @param {TreeNode} root
140+
* @return {number}
141+
*/
142+
maximumAverageSubtree(root) {
143+
return this.maxAverage(root).maxAverage;
144+
}
145+
146+
maxAverage(root) {
147+
if (root === null) {
148+
return new State(0, 0, 0);
149+
}
150+
151+
// postorder traversal, solve for both child nodes first.
152+
const left = this.maxAverage(root.left);
153+
const right = this.maxAverage(root.right);
154+
155+
// now find nodeCount, valueSum and maxAverage for current node `root`
156+
const nodeCount = left.nodeCount + right.nodeCount + 1;
157+
const sum = left.valueSum + right.valueSum + root.val;
158+
const maxAverage = Math.max(
159+
(1.0 * sum) / nodeCount, // average for current node
160+
Math.max(right.maxAverage, left.maxAverage) // max average from child nodes
161+
);
162+
163+
return new State(nodeCount, sum, maxAverage);
164+
}
165+
}
166+
```
167+
168+
::tabs-end
169+
170+
### Time & Space Complexity
171+
172+
- Time complexity: $O(N)$
173+
- Space complexity: $O(N)$
174+
175+
> Where $N$ is the number of nodes in the tree

0 commit comments

Comments
 (0)