def pruneTree(self, root: TreeNode) -> TreeNode:
     if root:
         root.left = self.pruneTree(root.left)
         root.right = self.pruneTree(root.right)
         if root.val or root.left or root.right:
             # The root node could not be pruned any longer.
             return root
Exemple #2
0
    def constructMaximumBinaryTree2(self, nums: List[int]) -> TreeNode:
        """
        Instead of finding the maximum number for each sub list every time, we
        simply use a stack which holds the numbers in descending order. Then
        we have:
            1. If the next number is less than the top of the stack, it is
                a candidate right node for the top of the stack, so we set it
                as the right node and also append it to the stack.
            2. Else, we keep popping from the stack until the stack is empty
                or the top of the stack is greater than the next number. Notice
                the last item popped from the stack will be the left node for
                the next number.
        """
        if not nums:
            return None

        stack = []
        for num in nums:
            node, lastPoppedNode = TreeNode(num), None
            while stack and stack[-1].val < num:
                lastPoppedNode = stack.pop()

            node.left = lastPoppedNode
            if stack:
                stack[-1].right = node

            stack.append(node)

        return stack[0]  # The first item in the stack is our root node.
    def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
        if not nums:  # Empty tree.
            return None

        m = (len(nums) - 1) // 2
        root = TreeNode(nums[m])
        root.left = self.sortedArrayToBST(nums[:m])
        root.right = self.sortedArrayToBST(nums[m + 1:])
        return root
    def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
        if not root:
            return TreeNode(val)

        if val < root.val:
            root.left = self.insertIntoBST(root.left, val)
        else:
            root.right = self.insertIntoBST(root.right, val)

        return root
Exemple #5
0
        def do() -> TreeNode:
            currVal = next(vals)
            if currVal == '#':
                return None

            root = TreeNode(int(currVal))
            root.left = do()
            root.right = do()

            return root
Exemple #6
0
    def mergeTrees(self, t1: TreeNode, t2: TreeNode) -> TreeNode:
        if not t1:
            return t2

        if not t2:
            return t1

        t1.val += t2.val
        t1.left = self.mergeTrees(t1.left, t2.left)
        t1.right = self.mergeTrees(t1.right, t2.right)
        return t1
        def g(first: int, last: int) -> List[TreeNode]:
            rslt = []
            for root in range(first, last + 1):
                for leftNode in g(first, root - 1):
                    for rightNode in g(root + 1, last):
                        currNode = TreeNode(root)
                        currNode.left = leftNode
                        currNode.right = rightNode
                        rslt.append(currNode)

            return rslt or [None]  # Need to return [None] when rslt is empty.
Exemple #8
0
        def do(start: int, end: int) -> TreeNode:
            if end < start:
                return None

            maxIdx, maxNum = start, nums[start]
            for i in range(start + 1, end + 1):
                if nums[i] > maxNum:
                    maxIdx, maxNum = i, nums[i]

            root = TreeNode(maxNum)
            root.left = do(start, maxIdx - 1)
            root.right = do(maxIdx + 1, end)
            return root
        def check(n: int) -> list[TreeNode]:
            if n not in memo:
                rslt = []
                for i in range(n):
                    j = n - 1 - i
                    for left in check(i):
                        for right in check(j):
                            root = TreeNode(0)
                            root.left = left
                            root.right = right
                            rslt.append(root)

                memo[n] = rslt

            return memo[n]
    def create_tree(self, l: int, r: int) -> TreeNode:
        if l > r:
            return None

        m = (l + r) // 2

        left = self.create_tree(l, m - 1)

        root = TreeNode(self.currNodeInList.val)
        root.left = left

        self.currNodeInList = self.currNodeInList.next

        root.right = self.create_tree(m + 1, r)

        return root
Exemple #11
0
        def do(start: int, end: int) -> TreeNode:
            if start > end:
                return None

            if start == end:
                return TreeNode(preorder[start])

            rootVal = preorder[start]
            left = start + 1
            while left <= end and preorder[left] < rootVal:
                left += 1

            root = TreeNode(rootVal)
            root.left = do(start + 1, left - 1)
            root.right = do(left, end)
            return root
    def addOneRow(self, root: TreeNode, v: int, d: int) -> TreeNode:
        """
        Traverse the original tree level by level.
        """
        if d == 1:
            newRoot = TreeNode(v)
            newRoot.left = root
            return newRoot

        currNodes = [root]
        for _ in range(2, d):  # Get all the nodes on the d - 1 level.
            currNodes = [
                x for currNode in currNodes
                for x in (currNode.left, currNode.right) if x
            ]

        for currNode in currNodes:
            left, right = currNode.left, currNode.right
            currNode.left = TreeNode(v)
            currNode.right = TreeNode(v)
            currNode.left.left = left
            currNode.right.right = right

        return root
    def deleteNode(self, root: TreeNode, key: int) -> TreeNode:
        if not root:
            return None

        if root.val < key:
            root.right = self.deleteNode(root.right, key)
        elif root.val > key:
            root.left = self.deleteNode(root.left, key)
        else:  # Root is the target node to be deleted.
            if not root.left:
                return root.right
            elif not root.right:
                return root.left
            else:
                # Update the root value with the minimum value on its right
                # sub tree, then delete the old minimum tree node.
                curr = root.right
                while curr.left:
                    curr = curr.left

                root.val = curr.val
                root.right = self.deleteNode(root.right, root.val)

        return root
Exemple #14
0

class Solution:
    def pseudoPalindromicPaths(self, root: TreeNode) -> int:
        def search(currNode: TreeNode) -> None:
            if currNode:
                freqs[currNode.val - 1] += 1
                if not (currNode.left or currNode.right):
                    # Reach a leaf node.
                    if sum(f & 1 for f in freqs) <= 1:
                        self.paths += 1
                else:
                    search(currNode.left)
                    search(currNode.right)

                freqs[currNode.val - 1] -= 1  # Restore to search other paths.

        freqs = [0] * 9
        self.paths = 0
        search(root)
        return self.paths


r = TreeNode(2)
r.left = TreeNode(3)
r.right = TreeNode(1)
r.left.left = TreeNode(3)
r.left.right = TreeNode(1)
r.right.right = TreeNode(1)
print(Solution().pseudoPalindromicPaths(r))