Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 67e06dd

Browse files
feat: add solutions to lc problem: No.1457 (doocs#2004)
No.1457.Pseudo-Palindromic Paths in a Binary Tree
1 parent 0fa1357 commit 67e06dd

File tree

8 files changed

+419
-307
lines changed

8 files changed

+419
-307
lines changed

‎solution/1400-1499/1457.Pseudo-Palindromic Paths in a Binary Tree/README.md‎

Lines changed: 133 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,25 @@
5454

5555
<!-- 这里可写通用的实现逻辑 -->
5656

57-
先序遍历,统计每条路径上数字出现的次数,要满足伪回文路径,当且仅当路径上最多有一个数字的出现次数为奇数。
57+
**方法一:DFS + 位运算**
58+
59+
一条路径是伪回文路径,当且仅当该路径经过的节点值的出现次数为奇数的数字为 0ドル$ 个或 1ドル$ 个。
60+
61+
由于二叉树节点值的范围为 1ドル$ 到 9ドル,ドル因此对于每一条从根到叶子的路径,我们可以用一个长度为 10ドル$ 的二进制数 $mask$ 表示当前路径经过的节点值的出现状态,其中 $mask$ 的第 $i$ 位为 1ドル,ドル表示当前路径上节点值 $i$ 的出现次数为奇数,否则表示其出现次数为偶数。那么,如果一条路径是伪回文路径,需要满足 $mask \&(mask - 1) = 0,ドル其中 $\&$ 表示按位与运算。
62+
63+
基于以上分析,我们可以使用深度优先搜索的方法计算路径数。我们定义一个函数 $dfs(root, mask),ドル表示从当前 $root$ 节点开始,且当前节点的状态为 $mask$ 的所有伪回文路径的个数。那么答案就是 $dfs(root, 0)$。
64+
65+
函数 $dfs(root, mask)$ 的执行逻辑如下:
66+
67+
如果 $root$ 为空,则返回 0ドル$;
68+
69+
否则,令 $mask = mask \oplus 2^{root.val},ドル其中 $\oplus$ 表示按位异或运算。
70+
71+
如果 $root$ 是叶子节点,那么如果 $mask \&(mask - 1) = 0,ドル返回 1ドル,ドル否则返回 0ドル$;
72+
73+
如果 $root$ 不是叶子节点,返回 $dfs(root.left, mask) + dfs(root.right, mask)$。
74+
75+
时间复杂度 $O(n),ドル空间复杂度 $O(n)$。其中 $n$ 是二叉树的节点数。
5876

5977
<!-- tabs:start -->
6078

@@ -70,24 +88,16 @@
7088
# self.left = left
7189
# self.right = right
7290
class Solution:
73-
def pseudoPalindromicPaths(self, root: TreeNode) -> int:
74-
def dfs(root):
91+
def pseudoPalindromicPaths(self, root: Optional[TreeNode]) -> int:
92+
def dfs(root: Optional[TreeNode], mask: int):
7593
if root is None:
76-
return
77-
nonlocal ans, counter
78-
counter[root.val] += 1
94+
return 0
95+
mask ^= 1 << root.val
7996
if root.left is None and root.right is None:
80-
if sum(1 for i in range(1, 10) if counter[i] % 2 == 1) < 2:
81-
ans += 1
82-
else:
83-
dfs(root.left)
84-
dfs(root.right)
85-
counter[root.val] -= 1
86-
87-
ans = 0
88-
counter = [0] * 10
89-
dfs(root)
90-
return ans
97+
return int((mask & (mask - 1)) == 0)
98+
return dfs(root.left, mask) + dfs(root.right, mask)
99+
100+
return dfs(root, 0)
91101
```
92102

93103
### **Java**
@@ -111,40 +121,19 @@ class Solution:
111121
* }
112122
*/
113123
class Solution {
114-
private int ans;
115-
private int[] counter;
116-
117124
public int pseudoPalindromicPaths(TreeNode root) {
118-
ans = 0;
119-
counter = new int[10];
120-
dfs(root);
121-
return ans;
125+
return dfs(root, 0);
122126
}
123127

124-
private void dfs(TreeNode root) {
128+
private int dfs(TreeNode root, intmask) {
125129
if (root == null) {
126-
return;
130+
return0;
127131
}
128-
++counter[root.val];
132+
mask ^=1<<root.val;
129133
if (root.left == null && root.right == null) {
130-
if (check(counter)) {
131-
++ans;
132-
}
133-
} else {
134-
dfs(root.left);
135-
dfs(root.right);
136-
}
137-
--counter[root.val];
138-
}
139-
140-
private boolean check(int[] counter) {
141-
int n = 0;
142-
for (int i = 1; i < 10; ++i) {
143-
if (counter[i] % 2 == 1) {
144-
++n;
145-
}
134+
return (mask & (mask - 1)) == 0 ? 1 : 0;
146135
}
147-
return n <2;
136+
return dfs(root.left, mask) + dfs(root.right, mask);
148137
}
149138
}
150139
```
@@ -165,30 +154,18 @@ class Solution {
165154
*/
166155
class Solution {
167156
public:
168-
int ans;
169-
vector<int> counter;
170-
171157
int pseudoPalindromicPaths(TreeNode* root) {
172-
ans = 0;
173-
counter.resize(10);
174-
dfs(root);
175-
return ans;
176-
}
177-
178-
void dfs(TreeNode* root) {
179-
if (!root) return;
180-
++counter[root->val];
181-
if (!root->left && !root->right) {
182-
int n = 0;
183-
for (int i = 1; i < 10; ++i)
184-
if (counter[i] % 2 == 1)
185-
++n;
186-
if (n < 2) ++ans;
187-
} else {
188-
dfs(root->left);
189-
dfs(root->right);
190-
}
191-
--counter[root->val];
158+
function<int(TreeNode*, int)> dfs = [&](TreeNode* root, int mask) {
159+
if (!root) {
160+
return 0;
161+
}
162+
mask ^= 1 << root->val;
163+
if (!root->left && !root->right) {
164+
return (mask & (mask - 1)) == 0 ? 1 : 0;
165+
}
166+
return dfs(root->left, mask) + dfs(root->right, mask);
167+
};
168+
return dfs(root, 0);
192169
}
193170
};
194171
```
@@ -205,32 +182,101 @@ public:
205182
* }
206183
*/
207184
func pseudoPalindromicPaths(root *TreeNode) int {
208-
ans := 0
209-
counter := make([]int, 10)
210-
var dfs func(root *TreeNode)
211-
dfs = func(root *TreeNode) {
185+
var dfs func(*TreeNode, int) int
186+
dfs = func(root *TreeNode, mask int) int {
212187
if root == nil {
213-
return
188+
return 0
214189
}
215-
counter[root.Val]++
190+
mask ^= 1 << root.Val
216191
if root.Left == nil && root.Right == nil {
217-
n := 0
218-
for i := 1; i < 10; i++ {
219-
if counter[i]%2 == 1 {
220-
n++
221-
}
222-
}
223-
if n < 2 {
224-
ans++
192+
if mask&(mask-1) == 0 {
193+
return 1
225194
}
226-
} else {
227-
dfs(root.Left)
228-
dfs(root.Right)
195+
return 0
229196
}
230-
counter[root.Val]--
197+
return dfs(root.Left, mask) + dfs(root.Right, mask)
231198
}
232-
dfs(root)
233-
return ans
199+
return dfs(root, 0)
200+
}
201+
```
202+
203+
### **TypeScript**
204+
205+
```ts
206+
/**
207+
* Definition for a binary tree node.
208+
* class TreeNode {
209+
* val: number
210+
* left: TreeNode | null
211+
* right: TreeNode | null
212+
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
213+
* this.val = (val===undefined ? 0 : val)
214+
* this.left = (left===undefined ? null : left)
215+
* this.right = (right===undefined ? null : right)
216+
* }
217+
* }
218+
*/
219+
220+
function pseudoPalindromicPaths(root: TreeNode | null): number {
221+
const dfs = (root: TreeNode | null, mask: number): number => {
222+
if (!root) {
223+
return 0;
224+
}
225+
mask ^= 1 << root.val;
226+
if (!root.left && !root.right) {
227+
return (mask & (mask - 1)) === 0 ? 1 : 0;
228+
}
229+
return dfs(root.left, mask) + dfs(root.right, mask);
230+
};
231+
return dfs(root, 0);
232+
}
233+
```
234+
235+
### **Rust**
236+
237+
```rust
238+
// Definition for a binary tree node.
239+
// #[derive(Debug, PartialEq, Eq)]
240+
// pub struct TreeNode {
241+
// pub val: i32,
242+
// pub left: Option<Rc<RefCell<TreeNode>>>,
243+
// pub right: Option<Rc<RefCell<TreeNode>>>,
244+
// }
245+
//
246+
// impl TreeNode {
247+
// #[inline]
248+
// pub fn new(val: i32) -> Self {
249+
// TreeNode {
250+
// val,
251+
// left: None,
252+
// right: None
253+
// }
254+
// }
255+
// }
256+
use std::rc::Rc;
257+
use std::cell::RefCell;
258+
259+
impl Solution {
260+
pub fn pseudo_palindromic_paths(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
261+
fn dfs(root: Option<Rc<RefCell<TreeNode>>>, mask: i32) -> i32 {
262+
if let Some(node) = root {
263+
let mut mask = mask;
264+
let val = node.borrow().val;
265+
mask ^= 1 << val;
266+
267+
if node.borrow().left.is_none() && node.borrow().right.is_none() {
268+
return if (mask & (mask - 1)) == 0 { 1 } else { 0 };
269+
}
270+
271+
return (
272+
dfs(node.borrow().left.clone(), mask) + dfs(node.borrow().right.clone(), mask)
273+
);
274+
}
275+
0
276+
}
277+
278+
dfs(root, 0)
279+
}
234280
}
235281
```
236282

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /