代码随想录算法训练营第十六天 | 二叉树part04

96 阅读3分钟

代码随想录算法训练营第十六天 | 二叉树part04

513 找树左下角的值

image.png

思路:可以用层序遍历,一层一层的加入进去,然后输出最后一层的第一个数,就是最底层 最左边 节点的值。

def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
    if not root:
        return 
    deque = collections.deque([root])
    stack = []
    depth = 0
    while deque:
        level = []
        size = len(deque)
        for i in range(size):
            node = deque.popleft()
            level.append(node.val)
            if node.left:
                deque.append(node.left)
            if node.right:
                deque.append(node.right)
        depth += 1
        stack.append(level)
    return stack[depth-1][0]

迭代法:

定义一个函数,这个函数需要接收的参数是node和depth,如果depth比当前的深度大的话,就更新最大深度。

然后取到node对应的val。

然后再对其左右节点进行递归。

为什么只取一个值呢,因为我们只需要知道最底层 最左边 节点的值。


def findBottomLeftValue(self, root: TreeNode) -> int:
    self.max_depth = float('-inf')
    self.result = None
    self.traversal(root, 0)
    return self.result
​
def traversal(self, node, depth):
    if not node.left and not node.right:
        if depth > self.max_depth:
            self.max_depth = depth
            self.result = node.val
        return
​
    if node.left:
        self.traversal(node.left, depth+1)
    if node.right:
        self.traversal(node.right, depth+1)
112 路径总和

image.png

思路:之前做过257 二叉树的所有路径,和这道题几乎一样,我们只需要把所有路径都列出来,然后找到最大值就行了,但是很明显时间复杂度很高。所以我们简化一下,设置一个最大值,然后往左往右进行遍历。比如说遍历到左孩子,那就把左孩子的值加进来,然后如果遍历到右孩子,就把刚刚左孩子的值减掉,再加入右孩子的值。

def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
    stack = []
    if not root:
        return False
    result = []
    self.a(root,stack,result)
    if targetSum in result:
        return True
    else:
        return False
def a(self,node,stack,result):
    stack.append(node.val)
    if not node.left and not node.right:
        result.append(sum(stack))
    if node.left:
        self.a(node.left,stack,result)
        node1 = stack.pop()
    if node.right:
        self.a(node.right,stack,result)
        node1 =stack.pop()
113 路径求和II

image.png

思路:和上一题一模一样,但是得保存下来对应的数字。

def pathSum(self, root: Optional[TreeNode], targetSum: int):
    stack = []
    if not root:
        return []
    result = []
    result2 = []
    self.targetSum = targetSum
    self.a(root,stack,result,result2)
    return result2
def a(self,node,stack,result,result2):
    stack.append(node.val)
    if not node.left and not node.right:
        result.append(sum(stack))
        if sum(stack) == self.targetSum:
            list_ = []
            for i in stack:
                list_.append(i)
            result2.append(list_)
    if node.left:
        self.a(node.left,stack,result,result2)
        node1 = stack.pop()
    if node.right:
        self.a(node.right,stack,result,result2)
        node1 =stack.pop()
105 从前序与中序遍历序列构造二叉树

image.png

思路同下,只需要画出来下图就能做出来题目了。

image.png

def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
    if not preorder:
        return None
    root_val = preorder[0]
    root = TreeNode(root_val)
    seperator_idx = inorder.index(root_val)
    inorder_left = inorder[ : seperator_idx]
    inorder_right = inorder[seperator_idx + 1 :]
    preorder_left = preorder[ 1 : seperator_idx + 1]
    preorder_right = preorder[seperator_idx + 1 : ]
    root.left = self.buildTree(preorder_left , inorder_left)
    root.right = self.buildTree(preorder_right , inorder_right)
    return root
106 从中序与后序遍历序列构造二叉树

image.png

  • 第一步:如果数组大小为零的话,说明是空节点了。

    if not postorder :
        return None
    
  • 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。

    root_val = postorder[-1]
    root = TreeNode(root_val)
    
  • 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点

    seperator_idx = inorder.index(root_val)
    
  • 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)

    inorder_left = inorder[:seperator_idx]
    inorder_right = inorder[seperator_idx + 1:]
    
  • 第五步:切割后序数组,切成后序左数组和后序右数组

    postorder_left = postorder[:seperator_idx]
    postorder_right = postorder[seperator_idx:len(postprder) - 1]
    
  • 第六步:递归处理左区间和右区间

    root.left = self.buildTree(inorder_left,postorder_left)
    root.right = self.buildTree(inorder_right,postorder_right)
    ​
    return root
    

完整代码:

def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
    if not postorder:
        return None
    root_val = postorder[-1]
    root = TreeNode(root_val)
    seperator_idx = inorder.index(root_val)
    inorder_left = inorder[:seperator_idx]
    inorder_right = inorder[seperator_idx + 1:]
    postorder_left = postorder[:seperator_idx]
    postorder_right = postorder[seperator_idx:len(postorder) - 1]
    root.left = self.buildTree(inorder_left,postorder_left)
    root.right = self.buildTree(inorder_right,postorder_right)
    return root