class Solution(object):
    def is_balanced(self, root: TreeNode):
        if not root:
            return True
        return self.traverse(root) != -1

    def traverse(self, node):
        if not node:
            return 0
        left = self.traverse(node.left)
        if left == -1:
            return -1
        right = self.traverse(node.right)
        if right == -1:
            return -1
        if abs(left - right) > 1:
            return -1
        return max(left, right) + 1


if __name__ == "__main__":
    import sys
    sys.path.append("..")
    from playground.TreePlayground import BinaryTreeUtil
    root = BinaryTreeUtil.build_tree([1, 1, 1, 1, 1, None, 1])
    BinaryTreeUtil.pretty_print_tree(root)
    soln = Solution()
    print(soln.is_balanced(root))
            res.append(None)
            return
        res.append(node.val)
        self._encode(node.left, res)
        self._encode(node.right, res)

    def deserialize(self, data):
        if not data:
            return None
        self.i = 0
        self.data = data
        return self._decode()

    def _decode(self):
        if self.data[self.i] is None:
            self.i += 1
            return None
        root = TreeNode(self.data[self.i])
        self.i += 1
        root.left = self._decode()
        root.right = self._decode()
        return root

if __name__ == "__main__":
    codec = Codec()
    root = BinaryTreeUtil.build_tree([1,2,3,4,5,6,7,8])
    BinaryTreeUtil.pretty_print_tree(root)
    encode = codec.serialize(root)
    print(encode)
    root = codec.deserialize(encode)
    BinaryTreeUtil.pretty_print_tree(root)
import sys
sys.path.append("../../")
from playground.TreePlayground import BinaryTreeUtil, TreeNode

root = BinaryTreeUtil.build_tree([1, 2, 3])
BinaryTreeUtil.pretty_print_tree(root)
print("=====")


def double_tree(node: TreeNode):
    if not node:
        return
    left_child = node.left
    node.left = TreeNode(node.val)
    node.left.left = left_child
    double_tree(left_child)
    double_tree(node.right)


double_tree(root)
BinaryTreeUtil.pretty_print_tree(root)
class Solution(object):
    def vertical_sum(self, root):
        import collections
        self.leftmost = self.rightmost = 0
        self.res_dict = collections.Counter()
        self.traverse(root, 0)
        res = []
        for x in range(self.leftmost, self.rightmost + 1):
            res.append(self.res_dict[x])
        print(res)

    def traverse(self, node, x):
        if not node:
            return
        self.res_dict[x] += node.val
        self.leftmost = min(self.leftmost, x)
        self.rightmost = max(self.rightmost, x)
        self.traverse(node.left, x - 1)
        self.traverse(node.right, x + 1)


if __name__ == "__main__":
    import sys
    sys.path.append("../../")
    from playground.TreePlayground import BinaryTreeUtil
    root = BinaryTreeUtil.build_tree([3, 9, 8, 4, 0, 1, 7])
    soln = Solution()
    soln.vertical_sum(root)
    BinaryTreeUtil.pretty_print_tree(root)
import sys
sys.path.append("../../..")
from playground.TreePlayground import BinaryTreeUtil, TreeNode


class Traverser(object):
    def rev_level_order(self, root: TreeNode):
        import collections
        self.res = collections.deque()
        self.rev_level_order_helper(root, 0)
        return self.res
    
    def rev_level_order_helper(self, node: TreeNode, level: int):
        if not node:
            return
        if level + 1 > len(self.res):
            self.res.appendleft([])
        self.res[- (level + 1)].append(node.val)
        self.rev_level_order_helper(node.left, level + 1)
        self.rev_level_order_helper(node.right, level + 1)



root = BinaryTreeUtil.build_tree([1,2,3,4,5,6,7,8,9,10,11])
BinaryTreeUtil.pretty_print_tree(root)
Traverser().rev_level_order(root)