<p>Given a binary tree where node values are digits from 1 to 9. A path in the binary tree is said to be <strong>pseudo-palindromic</strong> if at least one permutation of the node values in the path is a palindrome.</p>

<p><em>Return the number of <strong>pseudo-palindromic</strong> paths going from the root node to leaf nodes.</em></p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<p><img alt="" src="https://assets.leetcode.com/uploads/2020/05/06/palindromic_paths_1.png" style="width: 300px; height: 201px;" /></p>

<pre>
<strong>Input:</strong> root = [2,3,1,3,1,null,1]
<strong>Output:</strong> 2 
<strong>Explanation:</strong> The figure above represents the given binary tree. There are three paths going from the root node to leaf nodes: the red path [2,3,3], the green path [2,1,1], and the path [2,3,1]. Among these paths only red path and green path are pseudo-palindromic paths since the red path [2,3,3] can be rearranged in [3,2,3] (palindrome) and the green path [2,1,1] can be rearranged in [1,2,1] (palindrome).
</pre>

<p><strong class="example">Example 2:</strong></p>

<p><strong><img alt="" src="https://assets.leetcode.com/uploads/2020/05/07/palindromic_paths_2.png" style="width: 300px; height: 314px;" /></strong></p>

<pre>
<strong>Input:</strong> root = [2,1,1,1,3,null,null,null,null,null,1]
<strong>Output:</strong> 1 
<strong>Explanation:</strong> The figure above represents the given binary tree. There are three paths going from the root node to leaf nodes: the green path [2,1,1], the path [2,1,3,1], and the path [2,1]. Among these paths only the green path is pseudo-palindromic since [2,1,1] can be rearranged in [1,2,1] (palindrome).
</pre>

<p><strong class="example">Example 3:</strong></p>

<pre>
<strong>Input:</strong> root = [9]
<strong>Output:</strong> 1
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li>The number of nodes in the tree is in the range <code>[1, 10<sup>5</sup>]</code>.</li>
	<li><code>1 &lt;= Node.val &lt;= 9</code></li>
</ul>

from collections import defaultdict
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right


class Solution:
    def __init__(self):
        self.pseudo_palindroms_count = 0
    def is_pseudo_palindrom(self, digits_count: dict[int, int], path_length: int) -> bool:
        """
        If the path length is odd, we can have the "extra" digit in the middle
            max_odd_count = 1
        If it's even, we need all digits to be even:
            max_odd_count = 0
        """
        # print(f"Checking {digits_count=}, {path_length=}")
        max_odd_count = 0 # for even path lengths
        if path_length%2!=0:
            max_odd_count = 1
        
        odd_count = 0
        for i in range(1, 11):
            if digits_count[i]%2 != 0:
                odd_count += 1
        # print(f"  Checking {max_odd_count=} and {odd_count=}")
        if odd_count == max_odd_count:
            return True
        return False
    
    def dfs_count(self, node: Optional[TreeNode], digits_count: dict[int, int], path_length: int):
        if not node:
            return
        
        digits_count[node.val] += 1 # When entering a node, update the count
        
        # print(f"{path_length*' '}At node {node.val=}")
        if not node.left and not node.right: # This is a leaf
            if self.is_pseudo_palindrom(digits_count, path_length+1):
                self.pseudo_palindroms_count += 1
        else:
            if node.left:
                self.dfs_count(node.left, digits_count, path_length+1)
            if node.right:
                self.dfs_count(node.right, digits_count, path_length+1)
    
        digits_count[node.val] -= 1 # When exiting the node, restore the count
        return
    
    def pseudoPalindromicPaths (self, root: Optional[TreeNode]) -> int:
        # Non pseudo-palindromic paths should be counted, that includes palindromic paths
        # When visiting the nodes, keep count of the digits
        # When reaching a leaf, if there is a single odd count,
        # then one of its permutations will be a pseudo palindromic string
        # 
        # The time complexity of this approach is O(n) where n is the number of nodes
        
        digits_count = {}
        for i in range(1, 11):
            digits_count[i] = 0
        
        self.dfs_count(root, digits_count, 0)
        
        return self.pseudo_palindroms_count
44000