• 314. Binary Tree Vertical Order Traversal


    https://leetcode.com/problems/binary-tree-vertical-order-traversal/#/description

    Given a binary tree, return the vertical order traversal of its nodes' values. (ie, from top to bottom, column by column).

    If two nodes are in the same row and column, the order should be from left to right.

    Examples:

    1. Given binary tree [3,9,20,null,null,15,7],
         3
        /
       /  
       9  20
          /
         /  
        15   7
      

      return its vertical order traversal as:

      [
        [9],
        [3,15],
        [20],
        [7]
      ]
      
    2. Given binary tree [3,9,8,4,0,1,7],
           3
          /
         /  
         9   8
        /  /
       /  /  
       4  01   7
      

      return its vertical order traversal as:

      [
        [4],
        [9],
        [3,0,1],
        [8],
        [7]
      ]
      
    3. Given binary tree [3,9,8,4,0,1,7,null,null,null,2,5] (0's right child is 2 and 1's left child is 5),
           3
          /
         /  
         9   8
        /  /
       /  /  
       4  01   7
          /
         /  
         5   2
      

      return its vertical order traversal as:

      [
        [4],
        [9,5],
        [3,0,1],
        [8,2],
        [7]
      ]
      
    Sol:
     
    Pretty much like Tree Level Order Print. 
     
    Create a list s to store the node and index/column of this node in the final output in the format of (index, col).
     
    Use a dictionary to get the pop pair from s.  The key is col/index, and the value is the value of the node. 
     
    If the left node exists, append the (left node, col - 1) to the list s. It is col - 1 because the left node shows in the previous index of the return list. 
     
    Likewise, if the right node exists, append the (right node, col + 1) to list s. It is col + 1 because the right node shows in the next index of the return list.
     
    In the end, return the value of the dictionary in the ascending way of keys.
     
    P.S. We use a list to store the (node, col) tuple. The pop the node and col from the tuple to the dictionary. The reasons why we still need the dictionary are 1) we need to return the value of node, not the node itself. Thus the value of the dictionary is node.val.  2) We will output node values in the ascdending order of cols. Thus, the key of the dictionary is the col. 
     
    To sum it up, the list is actually doing the heavy lifting.  
     
    # Definition for a binary tree node.
    class TreeNode(object):
        def __init__(self, x):
            self.val = x
            self.left = None
            self.right = None
    
    from collections import defaultdict
    
    class Solution(object):
        def verticalOrder(self, root):
            """
            :type root: TreeNode
            :rtype: List[List[int]]
            """
        
        
            cols = defaultdict(list)
            s = list()
            if root:
                # elements in s have the format of (node, index), where index shows the index/column if this node in the final output list.
                s.append((root, 0))
                while s:
                    node, col = s.pop(0)
                    # for cols dictionary, the key is col/index; the value is node.val
                    cols[col].append(node.val)
                    # the left subnode is on the left side of the tree, and according to the output format, it is at the previous index.
                    if node.left:
                        s.append((node.left, col - 1))
                    # the right subnode is on the right side of the tree, and according to the output format, it is at the next index.        
                    if node.right:
                        s.append((node.right, col + 1))
            # return a list. 
            return [cols[k] for k in sorted(cols.keys())]
     
     
    Note:
     
    1 from collections import defaultdict 
    should be written before the class Solution(object) line, otherwise it will raise error
     
    2 The usage of defaultdict is different from a dictionary. 
     
    When you get a nonexistent key from a dictionary, it wiill throw a KeyError whereas as for defaultdict, instead of throwing a KeyError, it will create  this item. 
     
    Usually, a Python dictionary throws a KeyError if you try to get an item with a key that is not currently in the dictionary. The defaultdict in contrast will simply create any items that you try to access (provided of course they do not exist yet). To create such a "default" item, it calls the function object that you pass in the constructor (more precisely, it's an arbitrary "callable" object, which includes function and type objects). For the first example, default items are created using int(), which will return the integer object 0. For the second example, default items are created using list(), which returns a new empty list object.
     
     
     
     
    3 A pythonic way to traverse a dictionary. 
     
    >>> x = [chr(i) for in range(9797 + 26)]
    >>> x
    ['a''b''c''d''e''f''g''h''i''j''k''l''m''n''o''p''q''r''s''t''u''v''w''x''y''z']
     
     
    >>> for i, v in enumerate(x):
        print("{} {}".format(i, v))
         
    0 a
    1 b
    2 c
    3 d
    4 e
    5 f
    6 g
    7 h
    8 i
    9 j
    10 k
    11 l
    12 m
    13 n
    14 o
    15 p
    16 q
    17 r
    18 s
    19 t
    20 u
    21 v
    22 w
    23 x
    24 y
    25 z
     
     # for i, v in enumerate(x)
    # "enumerate"  assigns the index of x to i, and the value of x to v 
     
     
     
    Similar problem:
     
     

    Tree Level Order Print - SOLUTION

    Given a binary tree of integers, print it in level order. The output will contain space between the numbers in the same level, and new line between different levels. For example, if the tree is:


    title


    The output should be:

    1 
    2 3 
    4 5 6
     

    Solution

    It won’t be practical to solve this problem using recursion, because recursion is similar to depth first search, but what we need here is breadth first search. So we will use a queue as we did previously in breadth first search. First, we’ll push the root node into the queue. Then we start a while loop with the condition queue not being empty. Then, at each iteration we pop a node from the beginning of the queue and push its children to the end of the queue. Once we pop a node we print its value and space.

    To print the new line in correct place we should count the number of nodes at each level. We will have 2 counts, namely current level count and next level count. Current level count indicates how many nodes should be printed at this level before printing a new line. We decrement it every time we pop an element from the queue and print it. Once the current level count reaches zero we print a new line. Next level count contains the number of nodes in the next level, which will become the current level count after printing a new line. We count the number of nodes in the next level by counting the number of children of the nodes in the current level. Understanding the code is easier than its explanation:

    class Node:
        def __init__(self, val=None):
            self.left = None
            self.right = None
            self.val =  val
     
     
     
     
    def levelOrderPrint(tree):
        if not tree:
            return
        nodes=collections.deque([tree])
        currentCount, nextCount = 1, 0
        while len(nodes)!=0:
            currentNode=nodes.popleft()
            currentCount-=1
            print currentNode.val,
            if currentNode.left:
                nodes.append(currentNode.left)
                nextCount+=1
            if currentNode.right:
                nodes.append(currentNode.right)
                nextCount+=1
            if currentCount==0:
                #finished printing current level
                print '
    ',
                currentCount, nextCount = nextCount, currentCount
     

    The time complexity of this solution is O(N), which is the number of nodes in the tree, so it’s optimal. Because we should visit each node at least once. The space complexity depends on maximum size of the queue at any point, which is the most number of nodes at one level. The worst case occurs when the tree is a complete binary tree, which means each level is completely filled with maximum number of nodes possible. In this case, the most number of nodes appear at the last level, which is (N+1)/2 where N is the total number of nodes. So the space complexity is also O(N). Which is also optimal while using a queue.

    Again, this is a very common tree interview question!

     

    Good Job!

  • 相关阅读:
    解决CHM文件不能浏览的问题
    SAS宏功能(下)
    python一句话求素数
    SAS与DBMS系统(SqlServer)通信
    CSS3圆角
    水平居中和垂直居中
    滚动条的控制
    快来给你的桌面加一只可爱的蟑螂吧 那个人
    自己用的PHP缓存类
    jquery 全反选
  • 原文地址:https://www.cnblogs.com/prmlab/p/7050374.html
Copyright © 2020-2023  润新知