def countPairs(self, root: TreeNode, distance: int) -> int:
     adjust = defaultdict(list)
     for node in TreeUtil.preOrderTraversalIterator(root):
         if node.left:
             adjust[node].append(node.left)
             adjust[node.left].append(node)
         if node.right:
             adjust[node].append(node.right)
             adjust[node.right].append(node)
     ans = 0
     for bfsRootNode in adjust:
         if bfsRootNode.left or bfsRootNode.right:
             continue
         queue = [(bfsRootNode, 0)]  # Node, _distance
         visited = set()
         while queue:
             node, _distance = queue.pop(0)
             if node in visited or _distance >= distance:
                 continue
             visited.add(node)
             for nextNode in filter(lambda node: node not in visited, adjust[node]):
                 if nextNode.left is None and nextNode.right is None:
                     if _distance < distance:
                         # print(bfsRootNode.val, nextNode.val)
                         ans += 1
                 else:
                     queue.append((nextNode, _distance + 1))
     return ans // 2
 def getChild2ParentMap(self, root: TreeNode):
     child2parent = {root: None}
     for node in TreeUtil.preOrderTraversalIterator(root):
         if node.left:
             child2parent[node.left] = node
         if node.right:
             child2parent[node.right] = node
     return child2parent
 def goodNodes(self, root: TreeNode) -> int:
     heap = TreeUtil.toValHeap(root)
     heap = [None] + heap
     count = 0
     for i in range(1, len(heap)):
         if heap[i] is not None and self.isGoodNode(heap, i):
             count += 1
     return count
 def isValidBST(self, root: TreeNode) -> bool:
     if not root:
         return False
     iterator = TreeUtil.inOrderTraversalIterator(root)
     previous = next(iterator)
     for node in iterator:
         if node.val <= previous.val:
             return False
         previous = node
     return True
Example #5
0
 def isSymmetric(self, root: TreeNode) -> bool:
     heap = TreeUtil.toValHeap(root)
     maxLevel = int(math.log2(len(heap) + 1))
     for level in range(1, maxLevel + 1):
         indexBegin = 2**(level - 1) - 1
         indexEnd = 2**level - 1 - 1
         while indexBegin < indexEnd:
             if heap[indexBegin] != heap[indexEnd]:
                 return False
             indexBegin += 1
             indexEnd -= 1
     return True
    def isSubtree(self, s: TreeNode, t: TreeNode) -> bool:
        if t is None:
            return s is None

        for subRootS in TreeUtil.postOrderTraversalIterator(s):
            if subRootS.val != t.val or TreeUtil.maxLevel(
                    subRootS) != TreeUtil.maxLevel(t):
                continue
            if TreeUtil.preOrderTraversal(subRootS) == TreeUtil.preOrderTraversal(t) \
                    and TreeUtil.inOrderTraversal(subRootS) == TreeUtil.inOrderTraversal(t):
                return True
        return False
Example #7
0
    def longestConsecutive_clumsy(self, root: TreeNode) -> int:
        def detectLongestPath(root: TreeNode, valIs: int) -> int:
            if not root or root.val != valIs:
                return 0
            leftLongestPathLength = detectLongestPath(root.left, valIs + 1)
            rightLongestPathLength = detectLongestPath(root.right, valIs + 1)
            if leftLongestPathLength > rightLongestPathLength:
                return 1 + leftLongestPathLength
            else:
                return 1 + rightLongestPathLength

        longest = 0
        for node in TreeUtil.inOrderTraversalIterator(root):
            longestLocal = detectLongestPath(node, node.val)
            if longestLocal > longest:
                longest = longestLocal
        return longest
 def maxDepth(self, root: TreeNode) -> int:
     return TreeUtil.maxLevel(root)
import threading

from test_script import TreeNode, TreeUtil, timer


class Codec:
    def serialize(self, root: TreeNode) -> str:
        """
        Encodes a tree to a single string.
        """
        return str(TreeUtil.toValHeapToDict(root)).replace(' ', '')

    @timer
    def deserialize(self, data: str) -> TreeNode:
        """
        Decodes your encoded data to tree.
        """
        return TreeUtil.createTreeByHeapExpressedByDict(eval(data))


root = TreeUtil.createTreeByPreInOrder(list(range(1, 1001)), list(range(1, 1001)))
treeDictStr = Codec().serialize(root)
Codec().deserialize(treeDictStr)
print(treeDictStr)
from test_script import TreeNode
from test_script import TreeUtil


class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        if not root:
            return False
        iterator = TreeUtil.inOrderTraversalIterator(root)
        previous = next(iterator)
        for node in iterator:
            if node.val <= previous.val:
                return False
            previous = node
        return True


print(Solution().isValidBST(
    TreeUtil.createBinaryTree([10, 5, 15, None, None, 6, 20])))
Example #11
0
 def deserialize(self, data: str) -> TreeNode:
     """
     Decodes your encoded data to tree.
     """
     return TreeUtil.createTreeByHeapExpressedByDict(eval(data))
from test_script import TreeNode, TreeUtil


class Solution:
    def isSubtree(self, s: TreeNode, t: TreeNode) -> bool:
        if t is None:
            return s is None

        for subRootS in TreeUtil.postOrderTraversalIterator(s):
            if subRootS.val != t.val or TreeUtil.maxLevel(
                    subRootS) != TreeUtil.maxLevel(t):
                continue
            if TreeUtil.preOrderTraversal(subRootS) == TreeUtil.preOrderTraversal(t) \
                    and TreeUtil.inOrderTraversal(subRootS) == TreeUtil.inOrderTraversal(t):
                return True
        return False


print(Solution().isSubtree(TreeUtil.createBinaryTree([1, 2, 3]),
                           TreeUtil.createBinaryTree([2, 3])))
class Solution:
    def isGoodNode(self, heap: List[object], index: int) -> bool:
        """
        使用heap判断第index个节点是否为好节点
        :param heap: 保存节点内容的堆(1-based index)
        :param index: 第index个节点(1-based index)
        :return:
        """
        nowNumber = heap[index]
        while index > 0:
            if heap[index] > nowNumber:
                return False
            index //= 2  # 找父亲节点
        return True

    def goodNodes(self, root: TreeNode) -> int:
        heap = TreeUtil.toValHeap(root)
        heap = [None] + heap
        count = 0
        for i in range(1, len(heap)):
            if heap[i] is not None and self.isGoodNode(heap, i):
                count += 1
        return count


tree = TreeUtil.createBinaryTree(
    [-5, -1, -4, None, None, -5, 0, None, None, None, None, -5, None, -1, 2])
tree.right.right.left.right = TreeUtil.createBinaryTree(
    [-3, None, -5, None, None, None, -4])
print(Solution().goodNodes(tree))
Example #14
0
 def serialize(self, root: TreeNode) -> str:
     """
     Encodes a tree to a single string.
     """
     return str(TreeUtil.toValHeapToDict(root)).replace(' ', '')
Example #15
0
                indexBegin += 1
                indexEnd -= 1
        return True

    def isSymmetric_fast(self, root: TreeNode) -> bool:
        def equals(node1: TreeNode, node2: TreeNode):
            if not node1 and not node2:
                return True
            elif (node1 and node2) is None:
                return False
            return node1.val == node2.val and equals(
                node1.left, node2.right) and equals(node1.right, node2.left)

        if not root:
            return True
        return equals(root.left, root.right)


speedtest([Solution().isSymmetric,
           Solution().isSymmetric_fast], [
               TreeUtil.createTreeByPreInOrder(
                   [1, 2, 4, 6, 5, 7, 9, 10, 8, 3, 5, 8, 7, 9, 10, 4, 6],
                   [4, 6, 2, 7, 10, 9, 5, 8, 1, 8, 5, 9, 10, 7, 3, 6, 4])
           ])
speedtest([Solution().isSymmetric,
           Solution().isSymmetric_fast], [
               TreeUtil.createTreeByPreInOrder(
                   [1, 2, 4, 6, 5, 7, 9, 10, 8, 2, 5, 8, 7, 9, 10, 4, 6],
                   [4, 6, 2, 7, 10, 9, 5, 8, 1, 8, 5, 9, 10, 7, 2, 6, 4])
           ])
    def lowestCommonAncestor(self, root: TreeNode, p: TreeNode,
                             q: TreeNode) -> TreeNode:
        def contain(root: TreeNode, findNode: TreeNode):
            return TreeUtil.findNodeByVal(root, findNode.val)

        def getCommonAncestor(node: TreeNode):
            if node is p:
                if contain(node, q):
                    return node
                return None
            elif node is q:
                if contain(node, p):
                    return node
                return None
            if contain(node.left, p):
                if contain(node.right, q):
                    return node
                return getCommonAncestor(node.left)
            elif contain(node.left, q):
                if contain(node.right, p):
                    return node
                return getCommonAncestor(node.right)

        return getCommonAncestor(root)


# root = TreeUtil.createBinaryTree([3, 5, 1, 6, 2, 0, 8, None, None, 7, 4])
root = TreeUtil.createBinaryTree([3, 5, 1, 6, 2, 0, 8, None, None, 7, 4])
print(Solution().lowestCommonAncestor(root, TreeUtil.findNodeByVal(root, 5),
                                      TreeUtil.findNodeByVal(root, 4)).val)
Example #17
0
                valIs = root.val
            else:
                nowLength += 1
            longest = max(longest, nowLength)
            detectLongestPath(root.left, valIs + 1, nowLength)
            detectLongestPath(root.right, valIs + 1, nowLength)

        longest = 0
        if not root:
            return 0
        detectLongestPath(root, root.val, 0)
        return longest


speedtest(
    [Solution().longestConsecutive,
     Solution().longestConsecutive_clumsy],
    [TreeUtil.createTreeByPreInOrder([1, 3, 2, 4, 5], [1, 2, 3, 4, 5])])
speedtest(
    [Solution().longestConsecutive,
     Solution().longestConsecutive_clumsy],
    [TreeUtil.createTreeByPreInOrder([2, 3, 2, 1], [2, 1, 2, 3])])
root = TreeNode(1)
node = root
for i in range(2, 5001):
    node.right = TreeNode(i)
    node = node.right
speedtest(
    [Solution().longestConsecutive,
     Solution().longestConsecutive_clumsy], [root])
 def contain(root: TreeNode, findNode: TreeNode):
     return TreeUtil.findNodeByVal(root, findNode.val)
Example #19
0
 def levelOrder(self, root: TreeNode) -> List[List[int]]:
     return TreeUtil.breadthFirstTraversal(root)
Example #20
0
 def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
     return TreeUtil.createTreeByPreInOrder(preorder, inorder)
        for node in TreeUtil.preOrderTraversalIterator(root):
            if node.left:
                adjust[node].append(node.left)
                adjust[node.left].append(node)
            if node.right:
                adjust[node].append(node.right)
                adjust[node.right].append(node)
        ans = 0
        for bfsRootNode in adjust:
            if bfsRootNode.left or bfsRootNode.right:
                continue
            queue = [(bfsRootNode, 0)]  # Node, _distance
            visited = set()
            while queue:
                node, _distance = queue.pop(0)
                if node in visited or _distance >= distance:
                    continue
                visited.add(node)
                for nextNode in filter(lambda node: node not in visited, adjust[node]):
                    if nextNode.left is None and nextNode.right is None:
                        if _distance < distance:
                            # print(bfsRootNode.val, nextNode.val)
                            ans += 1
                    else:
                        queue.append((nextNode, _distance + 1))
        return ans // 2


print(Solution().countPairs(TreeUtil.createTreeByHeap([1, 2, 3, None, 4, None, None]), 3))
print(Solution().countPairs(TreeUtil.createTreeByHeap([1, 2, 3, 4, 5, 6, 7]), 3))