题目描述
给你一棵二叉树,每个结点的值为 1
到 9
。我们称二叉树中的一条路径是 伪回文 的,当它满足:路径经过的所有结点值的排列中,存在一个回文序列。
请你返回从根到叶子结点的所有路径中 伪回文 路径的数目。
样例
输入:root = [2,3,1,3,1,null,1]
输出:2
解释:上图为给定的二叉树。总共有 3 条从根到叶子的路径:
红色路径 [2,3,3],绿色路径 [2,1,1] 和路径 [2,3,1]。
在这些路径中,只有红色和绿色的路径是伪回文路径,
因为红色路径 [2,3,3] 存在回文排列 [3,2,3],绿色路径 [2,1,1] 存在回文排列 [1,2,1]。
输入:root = [2,1,1,1,3,null,null,null,null,null,1]
输出:1
解释:上图为给定二叉树。总共有 3 条从根到叶子的路径:
绿色路径 [2,1,1] ,路径 [2,1,3,1] 和路径 [2,1]。
这些路径中只有绿色路径是伪回文路径,因为 [2,1,1] 存在回文排列 [1,2,1]。
输入:root = [9]
输出:1
限制
- 给定二叉树的结点数目在
1
到10^5
之间。 - 结点值在
1
到9
之间。
算法
(递归回溯) $O(n)$
- 如果路径是伪回文的,则路径上值的个数为奇数的值最多只能有 1 个。
- 递归遍历时,记录当前路径上值个数奇偶性。
- 由于结点值在
1
到9
之间,所以可以用一个二进制数字来替代集合。
时间复杂度
- 每个结点仅遍历一次,故时间复杂度为 $O(n)$。
空间复杂度
- 需要额外 $O(h)$ 的空间用于系统栈,其中 $h$ 是树的最大高度。
C++ 代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void solve(TreeNode *r, int &vals, int &ans) {
if (vals & (1 << r->val)) vals ^= 1 << r->val;
else vals |= 1 << r->val;
if (r->left) solve(r->left, vals, ans);
if (r->right) solve(r->right, vals, ans);
if (!r->left && !r->right) {
if (vals == 0 || (vals & (vals - 1)) == 0)
ans++;
}
if (vals & (1 << r->val)) vals ^= 1 << r->val;
else vals |= 1 << r->val;
}
int pseudoPalindromicPaths (TreeNode* root) {
int ans = 0;
int vals = 0;
solve(root, vals, ans);
return ans;
}
};