コード例 #1
0
 def naive(self, inorder, postorder):
     if inorder:  # CAUTION
         root = TreeNode(postorder.pop())
         i = inorder.index(root.val)
         root.left = self.buildTree(inorder[:i], postorder[:i])
         root.right = self.buildTree(inorder[i + 1:], postorder[i:])
         return root
    def iterative(self, preorder, inorder):
        if not preorder:
            return None
        # 根节点入栈
        root = TreeNode(preorder.pop(0))
        stack = [root]

        # 建立倒排索引,方便比较各节点在中序意义下的 大小关系
        m = {v: k for k, v in enumerate(inorder)}
        # 依次处理preorder中的后续各点
        for value in preorder:
            node = TreeNode(value)
            # 观察上一次循环的最后一句发现:栈顶相对于node是preorder意义上的左邻居
            # 而如果此时的node在中序意义上小于它,就说明node铁定是它的左孩子
            if m[value] < m[stack[-1].val]:
                stack[-1].left = node
            else:
                # 否则node在中序意义上大于栈顶
                # 说明当前元素可能位于栈顶元素或更高层元素的right位上
                # 具体是哪一层的right位呢?
                # 应当介于 p 层和 p-1 层之间;
                # 条件: 比p层靠右,同时比p-1层靠左
                while stack and m[stack[-1].val] < m[value]:
                    parent = stack.pop()
                # 循环跳出的时刻,记录的是最后一次满足条件的parent,即分析中的 p层
                #
                # 因为整体是按照preorder遍历的,而此时parent的左右孩子都已经入栈了
                # 后面处理的各节点不可能上溯到该parent, parent不再需要(已抛出栈无妨)
                parent.right = node
            stack.append(node)
        return root
 def pop_pre(self, preorder, inorder):
     # 不断抛preorder,而inorder不动,只是定位
     if inorder:
         # 这一步反复调用index(),直接跑是O(n); 可以用hash缓存好
         idx = inorder.index(preorder.pop(0))
         root = TreeNode(inorder[idx])
         # root已经抛掉了,preorder开头部分就是left
         root.left = self.pop_pre(preorder, inorder[:idx])
         # root和left子树已经处理完,相应元素都已经抛空;preorder的头部仍然直接可用
         root.right = self.pop_pre(preorder, inorder[idx + 1:])
         return root
コード例 #4
0
 def mergeTrees(self, t1, t2):
     if t1 is None and t2 is None:
         return None
     elif t1 is None:
         return t2
     elif t2 is None:
         return t1
     else:
         node = TreeNode(t1.val + t2.val)
         node.left = self.mergeTrees(t1.left, t2.left)
         node.right = self.mergeTrees(t1.right, t2.right)
         return node
 def build(stop):
     # 如果还没有处理到上一层认为的根
     if inorder and inorder[0] != stop:
         # 找到这一层的根
         root = TreeNode(preorder.pop(0))
         # 直接在比较完整的inorder上处理直到遇到Stop为止
         # 避免了index()操作的O(n)
         root.left = build(stop=root.val)
         inorder.pop(0)  # 当前层的左子树处理完了,抛当前层的根
         # 处理当前层的右子树;在上层的stop值之前的部分inorder可用
         root.right = build(stop=stop)
         return root
 def naive(self, preorder, inorder):
     if not preorder:
         return None
     # find root_val in inorder
     root_val = preorder[0]
     root_idx = inorder.index(root_val)
     # recurse
     L = self.naive(preorder[1:1 + root_idx], inorder[:root_idx])
     R = self.naive(preorder[1 + root_idx:], inorder[root_idx + 1:])
     # merge
     root = TreeNode(root_val)
     root.left, root.right = L, R
     return root
コード例 #7
0
 def iterative(self, inorder, postorder):
     if not postorder:  # CAUTION
         return None
     m = {v: k for k, v in enumerate(inorder)}
     root = TreeNode(postorder.pop())
     stack = [root]
     for v in postorder[::-1]:  # 注意逆序
         n = TreeNode(v)  # CAUTION
         if m[v] > m[stack[-1].val]:
             stack[-1].right = n
         else:
             while stack and m[v] < m[stack[-1].val]:
                 parent = stack.pop()
             parent.left = n
         stack.append(n)
     return root
コード例 #8
0
class Solution(object):
    def bfs(self, root):
        if not root:
            return 0
        row, depth = [root], 1
        while row:
            nrow = []
            for n in row:
                kids = tuple(e for e in (n.left, n.right) if e)
                if not kids:  # 上一层的某个节点是叶子节点
                    return depth
                nrow += kids
            row, depth = nrow, depth + 1
        assert False

    def dfs(self, root):
        if not root:
            return 0
        l, r = self.dfs(root.left), self.dfs(root.right)
        # 如果两边都非零,就取min+1 ; 否则取较深那边+1
        return (1 + min(l, r)) if (l and r) else (l + r + 1)

    def minDepth(self, root):
        return self.bfs(root)
        # return self.dfs(root)


if __name__ == '__main__':
    root = TreeNode.from_json('[3,9,20,null,null,15,7]')
    print(Solution().bfs(root))
コード例 #9
0
    def bfs(self, root):
        res = []
        q = [root] if root else []
        while q:
            res.append(q[-1].val)  # CAUTION
            q = [k for n in q for k in (n.left, n.right) if k]
        return res

    def dfs(self, root):
        rightmost_value_at_depth = []
        stack = [(root, 0)]  # tuple<node, depth>
        while stack:
            node, depth = stack.pop()
            if node:
                # 利用栈的性质,每个新层都是尽可能靠右的首次到达
                if depth >= len(rightmost_value_at_depth):
                    rightmost_value_at_depth.append(node.val)
                # 注意right后进先出;抛栈的时候才改记录;所以结果是尽量靠右
                stack.append((node.left, depth + 1))
                stack.append((node.right, depth + 1))
        return rightmost_value_at_depth

    def rightSideView(self, root):
        # return self.bfs(root)
        return self.dfs(root)


if __name__ == '__main__':
    res = Solution().rightSideView(TreeNode(1))
    print(res)