Pseudo-Palindromic Paths in a Binary Tree

medium tree dfs bit manipulation bitmask

Problem

Each tree node's value is 1..9. A path from root to leaf is pseudo-palindromic if its multiset of values can be rearranged into a palindrome. Count such paths.

Inputroot = [2,3,1,3,1,null,1]
Output2
Paths 2-3-3 and 2-1-1 both have at most one odd-count digit.

def pseudo_palindromic_paths(root):
    ans = 0
    def dfs(node, mask):
        nonlocal ans
        if not node: return
        mask ^= 1 << node.val
        if not node.left and not node.right:
            if mask & (mask - 1) == 0: ans += 1
            return
        dfs(node.left, mask); dfs(node.right, mask)
    dfs(root, 0)
    return ans
function pseudoPalindromicPaths(root) {
  let ans = 0;
  function dfs(n, mask) {
    if (!n) return;
    mask ^= 1 << n.val;
    if (!n.left && !n.right) { if ((mask & (mask - 1)) === 0) ans++; return; }
    dfs(n.left, mask); dfs(n.right, mask);
  }
  dfs(root, 0);
  return ans;
}
class Solution {
    int ans = 0;
    public int pseudoPalindromicPaths(TreeNode root) { dfs(root, 0); return ans; }
    void dfs(TreeNode n, int mask) {
        if (n == null) return;
        mask ^= 1 << n.val;
        if (n.left == null && n.right == null) { if ((mask & (mask - 1)) == 0) ans++; return; }
        dfs(n.left, mask); dfs(n.right, mask);
    }
}
class Solution {
    int ans = 0;
public:
    int pseudoPalindromicPaths(TreeNode* root) { dfs(root, 0); return ans; }
    void dfs(TreeNode* n, int mask) {
        if (!n) return;
        mask ^= 1 << n->val;
        if (!n->left && !n->right) { if ((mask & (mask - 1)) == 0) ans++; return; }
        dfs(n->left, mask); dfs(n->right, mask);
    }
};
Time: O(n) Space: O(h)