Skip to content

Commit 3eda552

Browse files
committed
feat: add solutions to lc problem: No.1612
No.1612.Check If Two Expression Trees are Equivalent
1 parent fdb3e05 commit 3eda552

File tree

6 files changed

+392
-197
lines changed

6 files changed

+392
-197
lines changed

solution/1600-1699/1612.Check If Two Expression Trees are Equivalent/README.md

Lines changed: 161 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@
5858

5959
<!-- 这里可写通用的实现逻辑 -->
6060

61+
**方法一:递归**
62+
63+
我们定义一个计数器 $cnt$,用于统计每个字母出现的次数。
64+
65+
然后我们分别对两棵二叉表达式树进行深度优先搜索,如果字母出现在左子树,则 $cnt$ 中对应的字母的值加 $1$,如果出现在右子树,则 $cnt$ 中对应的字母的值减 $1$。
66+
67+
最后,我们遍历 $cnt$,如果所有字母的值都为 $0$,则返回 `true`,否则返回 `false`
68+
69+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉表达式树的节点个数。
70+
6171
<!-- tabs:start -->
6272

6373
### **Python3**
@@ -73,18 +83,18 @@
7383
# self.right = right
7484
class Solution:
7585
def checkEquivalence(self, root1: 'Node', root2: 'Node') -> bool:
76-
counter = [0] * 26
77-
78-
def dfs(root, incr):
79-
if root:
80-
dfs(root.left, incr)
81-
dfs(root.right, incr)
82-
if root.val != '+':
83-
counter[ord(root.val) - ord('a')] += incr
84-
86+
def dfs(root, v):
87+
if root is None:
88+
return
89+
if root.val != '+':
90+
cnt[root.val] += v
91+
dfs(root.left, v)
92+
dfs(root.right, v)
93+
94+
cnt = Counter()
8595
dfs(root1, 1)
8696
dfs(root2, -1)
87-
return counter.count(0) == 26
97+
return all(x == 0 for x in cnt.values())
8898
```
8999

90100
```python
@@ -96,23 +106,18 @@ class Solution:
96106
# self.right = right
97107
class Solution:
98108
def checkEquivalence(self, root1: 'Node', root2: 'Node') -> bool:
99-
def calc(ans, left, right, op):
100-
for i in range(26):
101-
if op == '+':
102-
ans[i] = left[i] + right[i]
103-
else:
104-
ans[i] = left[i] - right[i]
105-
106109
def dfs(root):
107-
ans = [0] * 26
108-
if not root:
109-
return ans
110-
if root.val in ['+', '-']:
111-
left, right = dfs(root.left), dfs(root.right)
112-
calc(ans, left, right, root.val)
110+
cnt = [0] * 26
111+
if root is None:
112+
return cnt
113+
if root.val in '+-':
114+
l, r = dfs(root.left), dfs(root.right)
115+
k = 1 if root.val == '+' else -1
116+
for i in range(26):
117+
cnt[i] += l[i] + r[i] * k
113118
else:
114-
ans[ord(root.val) - ord('a')] += 1
115-
return ans
119+
cnt[ord(root.val) - ord('a')] += 1
120+
return cnt
116121

117122
return dfs(root1) == dfs(root2)
118123
```
@@ -138,29 +143,28 @@ class Solution:
138143
* }
139144
*/
140145
class Solution {
141-
private int[] counter;
146+
private int[] cnt = new int[26];
142147

143148
public boolean checkEquivalence(Node root1, Node root2) {
144-
counter = new int[26];
145149
dfs(root1, 1);
146150
dfs(root2, -1);
147-
for (int n : counter) {
148-
if (n != 0) {
151+
for (int x : cnt) {
152+
if (x != 0) {
149153
return false;
150154
}
151155
}
152156
return true;
153157
}
154158

155-
private void dfs(Node root, int incr) {
159+
private void dfs(Node root, int v) {
156160
if (root == null) {
157161
return;
158162
}
159-
dfs(root.left, incr);
160-
dfs(root.right, incr);
161163
if (root.val != '+') {
162-
counter[root.val - 'a'] += incr;
164+
cnt[root.val - 'a'] += v;
163165
}
166+
dfs(root.left, v);
167+
dfs(root.right, v);
164168
}
165169
}
166170
```
@@ -183,35 +187,32 @@ class Solution {
183187
*/
184188
class Solution {
185189
public boolean checkEquivalence(Node root1, Node root2) {
186-
int[] ans1 = dfs(root1);
187-
int[] ans2 = dfs(root2);
190+
int[] cnt1 = dfs(root1);
191+
int[] cnt2 = dfs(root2);
188192
for (int i = 0; i < 26; ++i) {
189-
if (ans1[i] != ans2[i]) {
193+
if (cnt1[i] != cnt2[i]) {
190194
return false;
191195
}
192196
}
193197
return true;
194198
}
195199

196200
private int[] dfs(Node root) {
197-
int[] ans = new int[26];
201+
int[] cnt = new int[26];
198202
if (root == null) {
199-
return ans;
203+
return cnt;
200204
}
201205
if (root.val == '+' || root.val == '-') {
202-
int[] left = dfs(root.left);
203-
int[] right = dfs(root.right);
204-
calc(ans, left, right, root.val);
206+
int[] l = dfs(root.left);
207+
int[] r = dfs(root.right);
208+
int k = root.val == '+' ? 1 : -1;
209+
for (int i = 0; i < 26; ++i) {
210+
cnt[i] += l[i] + r[i] * k;
211+
}
205212
} else {
206-
++ans[root.val - 'a'];
207-
}
208-
return ans;
209-
}
210-
211-
private void calc(int[] ans, int[] left, int[] right, char op) {
212-
for (int i = 0; i < 26; ++i) {
213-
ans[i] = op == '+' ? left[i] + right[i] : left[i] - right[i];
213+
cnt[root.val - 'a']++;
214214
}
215+
return cnt;
215216
}
216217
}
217218
```
@@ -232,20 +233,26 @@ class Solution {
232233
*/
233234
class Solution {
234235
public:
235-
vector<int> counter;
236-
237236
bool checkEquivalence(Node* root1, Node* root2) {
238-
counter.resize(26);
237+
int cnt[26]{};
238+
function<void(Node*, int)> dfs = [&](Node* root, int v) {
239+
if (!root) {
240+
return;
241+
}
242+
if (root->val != '+') {
243+
cnt[root->val - 'a'] += v;
244+
}
245+
dfs(root->left, v);
246+
dfs(root->right, v);
247+
};
239248
dfs(root1, 1);
240249
dfs(root2, -1);
241-
return count(counter.begin(), counter.end(), 0) == 26;
242-
}
243-
244-
void dfs(Node* root, int incr) {
245-
if (!root) return;
246-
dfs(root->left, incr);
247-
dfs(root->right, incr);
248-
if (root->val != '+') counter[root->val - 'a'] += incr;
250+
for (int& x : cnt) {
251+
if (x) {
252+
return false;
253+
}
254+
}
255+
return true;
249256
}
250257
};
251258
```
@@ -265,27 +272,107 @@ public:
265272
class Solution {
266273
public:
267274
bool checkEquivalence(Node* root1, Node* root2) {
275+
function<vector<int>(Node*)> dfs = [&](Node* root) -> vector<int> {
276+
vector<int> cnt(26);
277+
if (!root) {
278+
return cnt;
279+
}
280+
if (root->val == '+' || root->val == '-') {
281+
auto l = dfs(root->left);
282+
auto r = dfs(root->right);
283+
int k = root->val == '+' ? 1 : -1;
284+
for (int i = 0; i < 26; ++i) {
285+
cnt[i] += l[i] + r[i] * k;
286+
}
287+
} else {
288+
cnt[root->val - 'a']++;
289+
}
290+
return cnt;
291+
};
268292
return dfs(root1) == dfs(root2);
269293
}
294+
};
295+
```
296+
297+
### **JavaScript**
270298

271-
vector<int> dfs(Node* root) {
272-
vector<int> ans(26);
273-
if (!root) return ans;
274-
if (root->val == '+' || root->val == '-')
275-
{
276-
auto left = dfs(root->left);
277-
auto right = dfs(root->right);
278-
calc(ans, left, right, root->val);
279-
return ans;
299+
```js
300+
/**
301+
* Definition for a binary tree node.
302+
* function Node(val, left, right) {
303+
* this.val = (val===undefined ? " " : val)
304+
* this.left = (left===undefined ? null : left)
305+
* this.right = (right===undefined ? null : right)
306+
* }
307+
*/
308+
/**
309+
* @param {Node} root1
310+
* @param {Node} root2
311+
* @return {boolean}
312+
*/
313+
var checkEquivalence = function (root1, root2) {
314+
const cnt = new Array(26).fill(0);
315+
const dfs = (root, v) => {
316+
if (!root) {
317+
return;
318+
}
319+
if (root.val !== '+') {
320+
cnt[root.val.charCodeAt(0) - 'a'.charCodeAt(0)] += v;
321+
}
322+
dfs(root.left, v);
323+
dfs(root.right, v);
324+
};
325+
dfs(root1, 1);
326+
dfs(root2, -1);
327+
for (const x of cnt) {
328+
if (x) {
329+
return false;
280330
}
281-
++ans[root->val - 'a'];
282-
return ans;
283331
}
332+
return true;
333+
};
334+
```
284335

285-
void calc(vector<int>& ans, vector<int>& left, vector<int>& right, char op) {
286-
for (int i = 0; i < 26; ++i)
287-
ans[i] = op == '+' ? left[i] + right[i] : left[i] - right[i];
336+
```js
337+
/**
338+
* Definition for a binary tree node.
339+
* function Node(val, left, right) {
340+
* this.val = (val===undefined ? " " : val)
341+
* this.left = (left===undefined ? null : left)
342+
* this.right = (right===undefined ? null : right)
343+
* }
344+
*/
345+
/**
346+
* @param {Node} root1
347+
* @param {Node} root2
348+
* @return {boolean}
349+
*/
350+
var checkEquivalence = function (root1, root2) {
351+
const dfs = root => {
352+
const cnt = new Array(26).fill(0);
353+
if (!root) {
354+
return cnt;
355+
}
356+
if (root.val === '+' || root.val === '-') {
357+
const l = dfs(root.left);
358+
const r = dfs(root.right);
359+
const k = root.val === '+' ? 1 : -1;
360+
for (let i = 0; i < 26; ++i) {
361+
cnt[i] = l[i] + k * r[i];
362+
}
363+
} else {
364+
cnt[root.val.charCodeAt(0) - 'a'.charCodeAt(0)]++;
365+
}
366+
return cnt;
367+
};
368+
const cnt1 = dfs(root1);
369+
const cnt2 = dfs(root2);
370+
for (let i = 0; i < 26; ++i) {
371+
if (cnt1[i] !== cnt2[i]) {
372+
return false;
373+
}
288374
}
375+
return true;
289376
};
290377
```
291378

0 commit comments

Comments
 (0)