Skip to content

LeetCode: 1457-Pseudo-Palindromic Paths in a Binary Tree 解題紀錄

Last Updated on 2022-09-14 by Clay

題目

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

Return the number of pseudo-palindromic paths going from the root node to leaf nodes.

Example 1:

Input: root = [2,3,1,3,1,null,1]
Output: 2 
Explanation: 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).

Example 2:

Input: root = [2,1,1,1,3,null,null,null,null,null,1]
Output: 1 
Explanation: 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).

Example 3:

Input: root = [9]
Output: 1


題目給定一個二元樹結構的根節點,我們需要計算在二元樹的走訪路徑中,究竟有多少條路徑走到底部時,節點中的值可以排列成『回文』。

比方說,[2, 3, 3] 可以被排列成 [3, 2, 3],所以這就是一條回文的路徑(path)。


解題思路

DFS 深度優先搜索

要依序把樹狀結構每條路徑走到底,我們自然就是使用 DFS 來實作。而在走訪到樹底部時,我們還需要判斷這條路徑上的節點值是否可以組成回文

可以組成回文的數值陣列有個特徵:每個數值的數量為奇數的數量最多最多可以是『一次』;換句話說,如果一個數值陣列中的有兩個數值出現的次數皆為奇數,則無論如何都無法組成回文。

所以在走訪的過程中,我還另外提出了一個 currPath 的陣列儲存數值出現的次數。從題目的規定來看,數值最大只能到 9,是故可以只開 10 個儲存空間的陣列儲存。


DFS 深度優先搜索複雜度

因為陣列的儲存空間我們可以預估為最多就是存十個數值,故為常數。

Time complexityO(n)
Space complexityO(1)


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 DFS(int& palindromeNum, TreeNode* root, vector<int>& currPath) {
        ++currPath[root->val];
        int odd = 0;
        
        if (root->left != nullptr) {
            DFS(palindromeNum, root->left, currPath);
        }
        
        if (root->right != nullptr) {
            DFS(palindromeNum, root->right, currPath);
        }
        
        if (root->left == nullptr && root->right == nullptr) {
            // Count odd number
            for (int& n: currPath) {
                odd += n % 2;
            }
            
            if (odd <= 1) {
                ++palindromeNum;
            }
        }
        
        --currPath[root->val];
    }
    
    int pseudoPalindromicPaths (TreeNode* root) {
        int palindromeNum = 0;
        vector<int> v(10, 0);
        
        DFS(palindromeNum, root, v);
        
        return palindromeNum;
    }
};




Python 範例程式碼

# 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.results = 0
        self.currPath = [0 for _ in range(10)]
    
    def dfs(self, root):
        self.currPath[root.val] += 1
        
        if root.left is not None:
            self.dfs(root.left)
            
        if root.right is not None:
            self.dfs(root.right)
            
        if (root.left is None and root.right is None):
            count = 0
            
            for n in self.currPath:
                count += n % 2
            
            if count <= 1:
                self.results += 1
                
        self.currPath[root.val] -= 1
    
    def pseudoPalindromicPaths (self, root: Optional[TreeNode]) -> int:
        self.dfs(root)
        
        return self.results
        

References


Read More

Leave a Reply