力扣刷题-二叉树-找树左下角的值

513 找树左下角的值

给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
示例 1:
力扣刷题-二叉树-找树左下角的值_第1张图片
示例 2:
力扣刷题-二叉树-找树左下角的值_第2张图片

思路

层序遍历

直接层序遍历,因为题目说了是最底层,最左边的值,所以就是层序遍历最后一层的第一个值。

class TreeNode(object):
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

# 法一 采用层序遍历
from collections import deque
class Solution(object):
    def findBottomLeftValue(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        queue = deque([root])
        result = []
        while queue:
            level_result = []
            for _ in range(len(queue)):
                node = queue.popleft()
                level_result.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            result.append(level_result)
        return result[-1][0] # 题目说了最底层

层序遍历法很好理解

递归法

我们来分析一下题目:在树的最后一行找到最左边的值。
首先要是最后一行,然后是最左边的值。
如果使用递归法,如何判断是最后一行呢,其实就是深度最大的叶子节点一定是最后一行。
那么如何找最左边的呢?可以使用前序遍历(当然中序,后序都可以,因为本题没有 中间节点的处理逻辑,只要左优先就行),保证优先左边搜索(相对右,因为题目说是最左边的),然后记录深度最大的叶子节点,此时就是树的最后一行最左边的值。
递归三部曲:

  1. 确定递归函数的参数和返回值

参数必须有要遍历的树的节点(采用node一般化),还有就是一个变量用来记录最长深度。
本题还需要类里的两个全局变量,max_depth用来记录最大深度,result记录最大深度最左节点的数值。(采用slef初始化)

# 1. 传入一个记录深度的变量 传入一个结点
def traversal(self, node, depth):
    # 2. 当结点是叶子结点的时候 就计算深度
  1. 确定终止条件

当遇到叶子节点的时候,就需要统计一下最大的深度了,所以需要遇到叶子节点来更新最大深度。

# 中
if not node.left and not node.right:
    if depth > self.max_depth:
        self.max_depth = depth
        self.result = node.val
  1. 确定单层递归的逻辑

在找最大深度的时候,递归的过程中依然要使用回溯,代码如下:

# 左
if node.left:
    depth += 1
    self.traversal(node.left, depth)
    depth -= 1 # 回溯

# 右
if node.right:
    depth += 1
    self.traversal(node.right, depth)
    depth -= 1 # 回溯

完整代码:

# 法二 采用递归法 巧妙利用深度来判断是否是最后一行 前序遍历
class Solution(object):
    def findBottomLeftValue(self, root):
        self.max_depth = float("-inf") # 记住写法
        self.result = None
        self.traversal(root, 0) # 初始深度赋值为0
        return self.result


    # 因为需要遍历来判断深度 所以写一个新函数(也可以不用)
    # 1. 传入一个记录深度的变量 传入一个结点
    def traversal(self, node, depth):
        # 2. 当结点是叶子结点的时候 就计算深度
        # 中
        if not node.left and not node.right:
            if depth > self.max_depth:
                self.max_depth = depth
                self.result = node.val
        # 左
        if node.left:
            depth += 1
            self.traversal(node.left, depth)
            depth -= 1 # 回溯
        
        # 右
        if node.right:
            depth += 1
            self.traversal(node.right, depth)
            depth -= 1 # 回溯

参考:
https://www.programmercarl.com/0513.%E6%89%BE%E6%A0%91%E5%B7%A6%E4%B8%8B%E8%A7%92%E7%9A%84%E5%80%BC.html

你可能感兴趣的:(leetcode刷题,leetcode,算法,数据结构,python)