-
Notifications
You must be signed in to change notification settings - Fork 111
/
count-univalue-subtrees.cc
94 lines (88 loc) · 1.99 KB
/
count-univalue-subtrees.cc
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
// Count Univalue Subtrees
/// recursive
class Solution {
bool f(TreeNode *x, int &r) {
if (! x) return true;
auto fl = f(x->left, r),
fr = f(x->right, r);
if (fl && fr && (! x->left || x->left->val == x->val) &&
(! x->right || x->right->val == x->val))
return r++, true;
return false;
}
public:
int countUnivalSubtrees(TreeNode *x) {
int r = 0;
f(x, r);
return r;
}
};
/// post-order traversal with stack
class Solution {
public:
int countUnivalSubtrees(TreeNode *x) {
int r = 0;
stack<pair<TreeNode*, bool>> s;
for(;;) {
for (; x; x = x->left)
s.push({x, true});
while (! s.empty() && s.top().first->right == x) {
bool f = s.top().second;
x = s.top().first;
s.pop();
r += f;
if (! s.empty())
s.top().second &= f && s.top().first->val == x->val;
}
if (s.empty())
break;
x = s.top().first->right;
}
return r;
}
};
/// Morris-like post-order traversal
class Solution {
void reverse_right_chain(TreeNode *x, TreeNode *y) {
TreeNode *z = x->right, *t;
while (x != y) {
t = z->right;
z->right = x;
x = z;
z = t;
}
}
public:
int countUnivalSubtrees(TreeNode *x) {
TreeNode aux(0), *y, *z, *t;
aux.left = x;
x = &aux;
int r = 0;
while (x) {
y = x->left;
if (y) {
while (y->right && y->right != x)
y = y->right;
if (y->right == x) {
reverse_right_chain(x->left, y);
t = NULL;
for (z = y; ; t = z, z = z->right) {
if (z->left && z->left->val != z->val || t && t->val != z->val)
z->val = INT_MIN;
else
r++;
if (z == x->left) break;
}
reverse_right_chain(y, x->left);
y->right = NULL;
} else {
y->right = x;
x = x->left;
continue;
}
}
x = x->right;
}
return r;
}
};