Skip to content

Commit 99c033a

Browse files
add count-univalue-subtrees.md article
1 parent 604bd6a commit 99c033a

File tree

1 file changed

+310
-0
lines changed

1 file changed

+310
-0
lines changed
Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
## 1. Depth First Search
2+
3+
::tabs-start
4+
5+
```python
6+
class Solution:
7+
def countUnivalSubtrees(self, root: Optional[TreeNode]) -> int:
8+
self.count = 0
9+
10+
def dfs(node):
11+
if node is None:
12+
return True
13+
14+
isLeftUniValue = dfs(node.left)
15+
isRightUniValue = dfs(node.right)
16+
17+
# If both the children form uni-value subtrees, we compare the value of
18+
# chidrens node with the node value.
19+
if isLeftUniValue and isRightUniValue:
20+
if node.left and node.val != node.left.val:
21+
return False
22+
if node.right and node.val != node.right.val:
23+
return False
24+
25+
self.count += 1
26+
return True
27+
# Else if any of the child does not form a uni-value subtree, the subtree
28+
# rooted at node cannot be a uni-value subtree.
29+
return False
30+
31+
dfs(root)
32+
return self.count
33+
```
34+
35+
```java
36+
class Solution {
37+
int count = 0;
38+
39+
public boolean dfs(TreeNode node) {
40+
if (node == null) {
41+
return true;
42+
}
43+
44+
boolean left = dfs(node.left);
45+
boolean right = dfs(node.right);
46+
47+
// If both the children form uni-value subtrees, we compare the value of
48+
// chidren's node with the node value.
49+
if (left && right) {
50+
if (node.left != null && node.left.val != node.val) {
51+
return false;
52+
}
53+
if (node.right != null && node.right.val != node.val) {
54+
return false;
55+
}
56+
count++;
57+
return true;
58+
}
59+
// Else if any of the child does not form a uni-value subtree, the subtree
60+
// rooted at node cannot be a uni-value subtree.
61+
return false;
62+
}
63+
64+
public int countUnivalSubtrees(TreeNode root) {
65+
dfs(root);
66+
return count;
67+
}
68+
}
69+
```
70+
71+
```cpp
72+
class Solution {
73+
public:
74+
int count = 0;
75+
76+
bool dfs(TreeNode* node) {
77+
if (node == nullptr) {
78+
return true;
79+
}
80+
81+
bool isLeftUniValue = dfs(node->left);
82+
bool isRightUniValue = dfs(node->right);
83+
84+
// If both the children form uni-value subtrees, we compare the value of
85+
// chidren's node with the node value.
86+
if (isLeftUniValue && isRightUniValue) {
87+
if (node->left != nullptr && node->left->val != node->val) {
88+
return false;
89+
}
90+
if (node->right != nullptr && node->right->val != node->val) {
91+
return false;
92+
}
93+
count++;
94+
return true;
95+
}
96+
// Else if any of the child does not form a uni-value subtree, the subtree
97+
// rooted at node cannot be a uni-value subtree.
98+
return false;
99+
}
100+
101+
int countUnivalSubtrees(TreeNode* root) {
102+
dfs(root);
103+
return count;
104+
}
105+
};
106+
```
107+
108+
```javascript
109+
class Solution {
110+
constructor() {
111+
this.count = 0;
112+
}
113+
114+
/**
115+
* @param {TreeNode} node
116+
* @return {boolean}
117+
*/
118+
dfs(node) {
119+
if (node === null) {
120+
return true;
121+
}
122+
123+
let left = this.dfs(node.left);
124+
let right = this.dfs(node.right);
125+
126+
// If both the children form uni-value subtrees, we compare the value of
127+
// children's node with the node value.
128+
if (left && right) {
129+
if (node.left !== null && node.left.val !== node.val) {
130+
return false;
131+
}
132+
if (node.right !== null && node.right.val !== node.val) {
133+
return false;
134+
}
135+
this.count++;
136+
return true;
137+
}
138+
139+
// Else if any of the child does not form a uni-value subtree, the subtree
140+
// rooted at node cannot be a uni-value subtree.
141+
return false;
142+
}
143+
144+
/**
145+
* @param {TreeNode} root
146+
* @return {number}
147+
*/
148+
countUnivalSubtrees(root) {
149+
this.count = 0;
150+
this.dfs(root);
151+
return this.count;
152+
}
153+
}
154+
```
155+
156+
::tabs-end
157+
158+
### Time & Space Complexity
159+
160+
- Time complexity: $O(n)$
161+
- Space complexity: $O(n)$
162+
163+
> Where $n$ is the number of nodes in the given binary tree
164+
165+
---
166+
167+
## 2. Depth First Search Without Using The Global Variable
168+
169+
::tabs-start
170+
171+
```python
172+
class Solution:
173+
def countUnivalSubtrees(self, root: Optional[TreeNode]) -> int:
174+
def dfs(node, count):
175+
if node is None:
176+
return True
177+
178+
isLeftUniValue = dfs(node.left, count)
179+
isRightUniValue = dfs(node.right, count)
180+
181+
# If both the children form uni-value subtrees, we compare the value of
182+
# chidrens node with the node value.
183+
if isLeftUniValue and isRightUniValue:
184+
if node.left and node.val != node.left.val:
185+
return False
186+
if node.right and node.val != node.right.val:
187+
return False
188+
189+
count[0] += 1
190+
return True
191+
# Else if any of the child does not form a uni-value subtree, the subtree
192+
# rooted at node cannot be a uni-value subtree.
193+
return False
194+
195+
count = [0]
196+
dfs(root, count)
197+
return count[0]
198+
```
199+
200+
```java
201+
class Solution {
202+
private boolean dfs(TreeNode root, int[] count) {
203+
if (root == null) {
204+
return true;
205+
}
206+
207+
boolean isLeftUnival = dfs(root.left, count);
208+
boolean isRightUnival = dfs(root.right, count);
209+
210+
if (isLeftUnival && isRightUnival &&
211+
(root.left == null || root.left.val == root.val) &&
212+
(root.right == null || root.right.val == root.val)
213+
) {
214+
count[0]++;
215+
return true;
216+
}
217+
218+
return false;
219+
}
220+
221+
public int countUnivalSubtrees(TreeNode root) {
222+
int[] count = new int[1];
223+
dfs(root, count);
224+
return count[0];
225+
}
226+
}
227+
```
228+
229+
```cpp
230+
class Solution {
231+
public:
232+
bool dfs(TreeNode* node, int& count) {
233+
if (node == nullptr) {
234+
return true;
235+
}
236+
237+
bool isLeftUniValue = dfs(node->left, count);
238+
bool isRightUniValue = dfs(node->right, count);
239+
240+
// If both the children form uni-value subtrees, we compare the value of
241+
// chidren's node with the node value.
242+
if (isLeftUniValue && isRightUniValue) {
243+
if (node->left != nullptr && node->left->val != node->val) {
244+
return false;
245+
}
246+
if (node->right != nullptr && node->right->val != node->val) {
247+
return false;
248+
}
249+
count++;
250+
return true;
251+
}
252+
// Else if any of the child does not form a uni-value subtree, the subtree
253+
// rooted at node cannot be a uni-value subtree.
254+
return false;
255+
}
256+
257+
int countUnivalSubtrees(TreeNode* root) {
258+
int count = 0;
259+
dfs(root, count);
260+
return count;
261+
}
262+
};
263+
```
264+
265+
```javascript
266+
class Solution {
267+
/**
268+
* @param {TreeNode} root
269+
* @param {number[]} count
270+
* @return {boolean}
271+
*/
272+
dfs(root, count) {
273+
if (root === null) {
274+
return true;
275+
}
276+
277+
let isLeftUnival = this.dfs(root.left, count);
278+
let isRightUnival = this.dfs(root.right, count);
279+
280+
if (isLeftUnival && isRightUnival &&
281+
(root.left === null || root.left.val === root.val) &&
282+
(root.right === null || root.right.val === root.val)
283+
) {
284+
count[0]++;
285+
return true;
286+
}
287+
288+
return false;
289+
}
290+
291+
/**
292+
* @param {TreeNode} root
293+
* @return {number}
294+
*/
295+
countUnivalSubtrees(root) {
296+
let count = [0];
297+
this.dfs(root, count);
298+
return count[0];
299+
}
300+
}
301+
```
302+
303+
::tabs-end
304+
305+
### Time & Space Complexity
306+
307+
- Time complexity: $O(n)$
308+
- Space complexity: $O(n)$
309+
310+
> Where $n$ is the number of nodes in the given binary tree

0 commit comments

Comments
 (0)