leetcode分类刷题:二叉树(一、简单的层序遍历)

二叉树的深度优先遍历题目是让我有点晕,先把简单的层序遍历总结下吧:配合队列进行的层序遍历在逻辑思维上自然直观,不容易出错

102. 二叉树的层序遍历

本题是二叉树的层序遍历模板:每次循环将一层节点出队,再将一层节点入队,也是所有可用层序遍历解二叉树题目的模板,只需要在模板里稍加改动即可解题

from typing import List, Optional, Union
from collections import deque
'''
102. 二叉树的层序遍历
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1:输入:root = [3,9,20,null,null,15,7]输出:[[3],[9,20],[15,7]]
题眼:基础
思路:利用队列实现
'''class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef buildBinaryTree(nums: List[Union[int, str]]) -> Optional[TreeNode]:if len(nums) == 0:return Noneif len(nums) == 1:return TreeNode(nums[0])# 1、转换为顺序存储tmpTree = []for n in nums:if n != 'null':tmpTree.append(TreeNode(n))else:tmpTree.append(None)# 2、转换为链式存储:双指针root = tmpTree[0]parent, child = 0, 1while child < len(tmpTree):if tmpTree[parent] != None:  # 双亲节点有效if tmpTree[child] != None:  # 左孩子节点有效tmpTree[parent].left = tmpTree[child]child += 1  # 指向右孩子if child < len(tmpTree) and tmpTree[child] != None:  # 右孩子节点存在且有效tmpTree[parent].right = tmpTree[child]child += 1  # 指向下个节点的左孩子parent += 1  # 更新遍历双亲节点return rootclass Solution:def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:if root == None:return []result = []que = deque()que.append(root)  # 队列初始值while len(que) > 0:size = len(que)  # 当前队列长度==二叉树一层的节点个数layer = []for _ in range(size):  # 一层遍历node = que.popleft()  # 记录下出队的节点layer.append(node.val)# 和之前深度遍历一样:空节点不入队,不然对None节点取值会出错if node.left != None:que.append(node.left)if node.right != None:que.append(node.right)result.append(layer)return resultif __name__ == "__main__":obj = Solution()while True:try:in_line = input().strip().split('=')[1].strip()[1: -1]nums = []if in_line != '':for n in in_line.split(','):if n != 'null':nums.append(int(n))else:nums.append(n)root = buildBinaryTree(nums)print(obj.levelOrder(root))except EOFError:break

107. 二叉树的层序遍历 II

“102. 二叉树的层序遍历”的结果反转/逆序即可

from typing import List, Optional, Union
from collections import deque
'''
107. 二叉树的层序遍历 II
给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
示例 1:输入:root = [3,9,20,null,null,15,7]输出:[[15,7],[9,20],[3]]
题眼:自底向上的层序遍历
思路:“102. 二叉树的层序遍历”的结果反转/逆序即可
'''class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef buildBinaryTree(nums: List[Union[int, str]]) -> Optional[TreeNode]:if len(nums) == 0:return Noneif len(nums) == 1:return TreeNode(nums[0])# 1、顺序存储tmpTree = []for n in nums:if n != 'null':tmpTree.append(TreeNode(n))else:tmpTree.append(None)# 2、链式存储:双指针root = tmpTree[0]parent, child = 0, 1while child < len(tmpTree):if tmpTree[parent] != None:  # 双亲节点有效if tmpTree[child] != None:  # 左孩子有效tmpTree[parent].left = tmpTree[child]child += 1  # 指向右孩子if child < len(tmpTree) and tmpTree[child] != None:  # 右孩子存在且有效tmpTree[parent].right = tmpTree[child]child += 1  # 指向下个节点的左孩子parent += 1return rootclass Solution:def levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:# 情况1、树为空if root == None:return []# 情况2、树不为空que = deque()que.append(root)result = []while len(que) > 0:size = len(que)  # 当前队列长度==二叉树一层的节点个数layer = []for _ in range(size):  # 一层遍历node = que.popleft()layer.append(node.val)if node.left != None:que.append(node.left)if node.right != None:que.append(node.right)result.append(layer)# 反转result# left, right = 0, len(result) - 1# while left < right:#     result[left], result[right] = result[right], result[left]#     left += 1#     right -= 1return result[::-1]if __name__ == "__main__":obj = Solution()while True:try:in_line = input().strip().split('=')[1].strip()[1: -1]nums = []if in_line != '':for n in in_line.split(','):if n != 'null':nums.append(int(n))else:nums.append(n)print(nums)root = buildBinaryTree(nums)print(obj.levelOrderBottom(root))except EOFError:break

429. N 叉树的层序遍历

一般 层序遍历的基础上,要访问每个节点的N个孩子

from typing import List, Optional, Union
from collections import deque
'''
429. N 叉树的层序遍历
给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。
树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。
示例 1:输入:root = [1,null,3,2,4,null,5,6]输出:[[1],[3,2,4],[5,6]]
题眼:N 叉树的层序遍历
思路:一般 层序遍历的基础上,要访问每个节点的N个孩子
'''class Node:def __init__(self, val=None, children=None):self.val = valself.children = childrenclass Solution:def levelOrder(self, root: Node) -> List[List[int]]:# 情况1、树为空if root == None:return []# 情况2、树不为空que = deque()que.append(root)result = []while len(que) > 0:size = len(que)layer = []for _ in range(size):  # 一层遍历node = que.popleft()layer.append(node.val)if node.children != None:for child in node.children:que.append(child)result.append(layer)return result

637. 二叉树的层平均值

from typing import List, Optional, Union
from collections import deque
'''
637. 二叉树的层平均值
给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。
示例 1:输入:root = [3,9,20,null,null,15,7]输出:[3.00000,14.50000,11.00000]解释:第 0 层的平均值为 3,第 1 层的平均值为 14.5,第 2 层的平均值为 11 。因此返回 [3, 14.5, 11] 。
题眼:每一层节点的平均值
思路:一般 层序遍历的基础上,计算每一层对应的平均值
'''class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef buildBinaryTree(nums: List[Union[int, str]]) -> Optional[TreeNode]:if len(nums) == 0:return Noneif len(nums) == 1:return TreeNode(nums[0])# 1、顺序存储tmpTree = []for n in nums:if n != 'null':tmpTree.append(TreeNode(n))else:tmpTree.append(None)# 2、转换为链式存储root = tmpTree[0]parent, child = 0, 1while child < len(tmpTree):if tmpTree[parent] != None:  # 双亲节点有效if tmpTree[child] != None:  # 左孩子节点有效tmpTree[parent].left = tmpTree[child]child += 1  # 指向右孩子if child < len(tmpTree) and tmpTree[child] != None:  # 右孩子存在且有效tmpTree[parent].right = tmpTree[child]child += 1  # 指向下个节点的左孩子parent += 1return rootclass Solution:def averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:que = deque()que.append(root)result = []while len(que) > 0:size = len(que)  # 当前队列长度==二叉树一层的节点个数s = 0for _ in range(size):  # 一层遍历node = que.popleft()s += node.valif node.left != None:que.append(node.left)if node.right != None:que.append(node.right)result.append(s / size)return resultif __name__ == "__main__":obj = Solution()while True:try:in_line = input().strip().split('=')[1].strip()[1: -1]nums = []if in_line != '':for n in in_line.split(','):if n != 'null':nums.append(int(n))else:nums.append(n)root = buildBinaryTree(nums)print(obj.averageOfLevels(root))except EOFError:break

515. 在每个树行中找最大值

from typing import List, Optional, Union
from collections import deque
'''
515. 在每个树行中找最大值
给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。
示例 1:输入: root = [1,3,2,5,3,null,9]输出: [1,3,9]
题眼:二叉树的层序遍历
思路:一般 层序遍历的基础上,记录每一行的最大值
'''class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef buildBinaryTree(nums: List[Union[int, str]]) -> Optional[TreeNode]:if len(nums) == 0:return Noneif len(nums) == 1:return TreeNode(nums[0])# 1、转换为顺序存储tmpTree = []for n in nums:if n != 'null':tmpTree.append(TreeNode(n))else:tmpTree.append(None)root = tmpTree[0]# 2、转换为链式存储:双指针parent, child = 0, 1while child < len(tmpTree):if tmpTree[parent] != None:  # 双亲节点有效if tmpTree[child] != None:  #  左孩子有效tmpTree[parent].left = tmpTree[child]child += 1  # 指向右孩子if child < len(tmpTree) and tmpTree[child] != None:  # 右孩子存在且有效tmpTree[parent].right = tmpTree[child]child += 1  # 指向下个节点的左孩子parent += 1return rootclass Solution:def largestValues(self, root: Optional[TreeNode]) -> List[int]:# 情况1、树为空if root == None:return []# 情况2、树不为空que = deque()que.append(root)result = []while len(que) > 0:size = len(que)  # 当前队列长度==二叉树一层的节点个数n = -float('inf')for _ in range(size):  # 一层遍历node = que.popleft()n = max(n, node.val)if node.left != None:que.append(node.left)if node.right != None:que.append(node.right)result.append(n)return resultif __name__ == "__main__":obj = Solution()while True:try:in_line = input().strip().split('=')[1].strip()[1: -1]nums = []if in_line != '':for n in in_line.split(','):if n != 'null':nums.append(int(n))else:nums.append(n)root = buildBinaryTree(nums)print(obj.largestValues(root))except EOFError:break

199. 二叉树的右视图

一般 层序遍历的基础上,返回每一层的最后一个元素

from typing import List, Optional, Union
from collections import deque
'''
199. 二叉树的右视图
给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
示例 1:输入:[1,2,3,null,5,null,4]输出:[1,3,4]
题眼:从顶部到底部  从右侧所能看到
思路:一般 层序遍历的基础上,返回每一层的最后一个元素
'''class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef buildBinaryTree(nums: List[Union[int, str]]) -> Optional[TreeNode]:if len(nums) == 0:return Noneif len(nums) == 1:return TreeNode(nums[0])# 1、 顺序存储tmpTree = []for n in nums:if n != 'null':tmpTree.append(TreeNode(n))else:tmpTree.append(None)# 2、链式存储:双指针root = tmpTree[0]parent, child = 0, 1while child < len(tmpTree):if tmpTree[parent] != None:  # 双亲结点有效if tmpTree[child] != None:  # 左孩子节点有效tmpTree[parent].left = tmpTree[child]child += 1  # 指向右孩子if child < len(tmpTree) and tmpTree[child] != None:  # 右孩子节点存在且有效tmpTree[parent].right = tmpTree[child]child += 1  # 指向下个节点的左孩子parent += 1return rootclass Solution:def rightSideView(self, root: Optional[TreeNode]) -> List[int]:# 情况1、树为空if root == None:return []# 情况2、树不为空que = deque()que.append(root)result = []while len(que) > 0:size = len(que)for i in range(size):  # 一层遍历node = que.popleft()if i == size - 1:  # 添加每一层的最后一个元素result.append(node.val)if node.left != None:que.append(node.left)if node.right != None:que.append(node.right)return resultif __name__ == "__main__":obj = Solution()while True:try:in_line = input().strip()[1: -1]nums = []if in_line != '':for n in in_line.split(','):if n != 'null':nums.append(int(n))else:nums.append(n)root = buildBinaryTree(nums)print(obj.rightSideView(root))except EOFError:break

513. 找树左下角的值

一般 层序遍历的基础上,访问每一层的每个元素时,都把第一个元素进行赋值即可

from typing import List, Optional, Union
from collections import deque
'''
513. 找树左下角的值
给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
示例 1:输入: root = [2,1,3]输出: 1
题眼:二叉树的层序遍历
思路:一般 层序遍历的基础上,访问每一层的每个元素时,都把第一个元素进行赋值即可
'''class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef buildBinaryTree(nums: List[Union[int, str]]) -> Optional[TreeNode]:if len(nums) == 0:return Noneif len(nums) == 1:return TreeNode(nums[0])# 1、顺序存储tmpTree = []for n in nums:if n != 'null':tmpTree.append(TreeNode(n))else:tmpTree.append(None)root = tmpTree[0]# 2、链式存储parent, child = 0, 1while child < len(tmpTree):if tmpTree[parent] != None:  # 双亲结点有效if tmpTree[child] != None:  # 左孩子节点有效tmpTree[parent].left = tmpTree[child]child += 1  # 指向右孩子if child < len(tmpTree) and tmpTree[child] != None:  # 右孩子存在且有效tmpTree[parent].right = tmpTree[child]child += 1  # 指向下一个节点的左孩子parent += 1return rootclass Solution:def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:que = deque()que.append(root)result = 0while len(que) > 0:size = len(que)for i in range(size):node = que.popleft()if i == 0:  # 总是获取层序遍历的每一层第一个值result = node.valif node.left != None:que.append(node.left)if node.right != None:que.append(node.right)return resultif __name__ == "__main__":obj = Solution()while True:try:in_line = input().strip().split('=')[1].strip()[1: -1]nums = []if in_line != '':for n in in_line.split(','):if n != 'null':nums.append(int(n))else:nums.append(n)root = buildBinaryTree(nums)print(obj.findBottomLeftValue(root))except EOFError:break

103. 二叉树的锯齿形层序遍历

一般 层序遍历的基础上,对结果的偶数个逆序一下

from typing import List, Optional, Union
from collections import deque
'''
103. 二叉树的锯齿形层序遍历
给你二叉树的根节点 root ,返回其节点值的 锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
示例 1:输入:root = [3,9,20,null,null,15,7]输出:[[3],[20,9],[15,7]]
题眼:基础
思路:一般 层序遍历的基础上,对结果的偶数个逆序一下
'''class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef buildBinaryTree(nums: List[Union[int, str]]) -> Optional[TreeNode]:if len(nums) == 0:return Noneif len(nums) == 1:return TreeNode(nums[0])# 1、转换为顺序存储tmpTree = []for n in nums:if n != 'null':tmpTree.append(TreeNode(n))else:tmpTree.append(None)# 2、转换为链式存储:双指针root = tmpTree[0]parent, child = 0, 1while child < len(tmpTree):if tmpTree[parent] != None:  # 双亲节点有效if tmpTree[child] != None:  # 左孩子节点有效tmpTree[parent].left = tmpTree[child]child += 1  # 指向右孩子if child < len(tmpTree) and tmpTree[child] != None:  # 右孩子节点存在且有效tmpTree[parent].right = tmpTree[child]child += 1  # 指向下个节点的左孩子parent += 1  # 更新遍历双亲节点return rootclass Solution:def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:# 情况1、树为空if root == None:return []# 情况2、树不为空que = deque()que.append(root)result = []while len(que) > 0:size = len(que)layer = []for _ in range(size):node = que.popleft()layer.append(node.val)if node.left != None:que.append(node.left)if node.right != None:que.append(node.right)result.append(layer)# 对结果的偶数个逆序一下for i in range(1, len(result), 2):result[i] = result[i][::-1]return resultif __name__ == "__main__":obj = Solution()while True:try:in_line = input().strip().split('=')[1].strip()[1: -1]nums = []if in_line != '':for n in in_line.split(','):if n != 'null':nums.append(int(n))else:nums.append(n)root = buildBinaryTree(nums)print(obj.zigzagLevelOrder(root))except EOFError:break

116. 填充每个节点的下一个右侧节点指针

一般 层序遍历的基础上,将每层的节点(除最后一个外)的next值指向下一个节点

from typing import List, Optional, Union
from collections import deque
'''
116. 填充每个节点的下一个右侧节点指针
给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node {int val;Node *left;Node *right;Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有next 指针都被设置为 NULL。
示例 1:输入:root = [1,2,3,4,5,6,7]输出:[1,#,2,3,#,4,5,6,7,#]解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化的输出按层序遍历排列,同一层节点由 next 指针连接,'#' 标志着每一层的结束。
题眼:二叉树的层序遍历(满二叉树)
思路:一般 层序遍历的基础上,将每层的节点(除最后一个外)的next值指向下一个节点
'''class Node:def __init__(self, val=0, left=None, right=None, next=None):self.val = valself.left = leftself.right = rightself.next = nextdef buildBinartTree(nums: List[Union[int]]) -> Optional[Node]:if len(nums) == 0:return []if len(nums) == 1:return Node(nums[0])# 1、转换为顺序存储tmpTree = []for n in nums:tmpTree.append(Node(n))root = tmpTree[0]# 2、转换为链式存储parent, child = 0, 1while child < len(tmpTree):tmpTree[parent].left = tmpTree[child]  # 满二叉树左孩子一定有效child += 1tmpTree[parent].right = tmpTree[child]  # 满二叉树右孩子一定存在且有效child += 1parent += 1return rootclass Solution:def connect(self, root: Optional[Node]) -> Optional[Node]:# 情况1、树为空if root == None:return root# 情况2、树不为空que = deque()que.append(root)while len(que) > 0:size = len(que)pre = Nonefor i in range(size):node = que.popleft()if i == 0:  # 记录每层第一个节点为prepre = nodeelse:  # 从每层第二个节点开始,都要给pre的next指针赋值pre.next = nodepre = nodeif node.left != None:que.append(node.left)if node.right != None:que.append(node.right)return rootif __name__ == "__main__":while True:try:in_line = input().strip().split('=')[1].strip()[1: -1]nums = []if in_line != '':for n in in_line.split(','):nums.append(int(n))print(nums)except EOFError:break

117. 填充每个节点的下一个右侧节点指针 II

一般 层序遍历的基础上,将每层的节点(除最后一个外)的next值指向下一个节点

from typing import List, Union, Optional
from collections import deque
'''
117. 填充每个节点的下一个右侧节点指针 II
给定一个二叉树
struct Node {int val;Node *left;Node *right;Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有next 指针都被设置为 NULL。
示例 1:输入:root = [1,2,3,4,5,null,7]输出:[1,#,2,3,#,4,5,7,#]解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化输出按层序遍历顺序(由 next 指针连接),'#' 表示每层的末尾。
题眼:二叉树的层序遍历(注意不是满二叉树)
思路:一般 层序遍历的基础上,将每层的节点(除最后一个外)的next值指向下一个节点
'''class Node:def __init__(self, val=0, left=None, right=None, next=None):self.val = valself.left = leftself.right = rightself.next = nextdef buildBinaryTree(nums: List[Union[int, str]]) -> Optional[Node]:if len(nums) == 0:return Noneif len(nums) == 1:return Node(nums[0])# 1、转换为顺序存储tmpTree = []for n in nums:if n != 'null':tmpTree.append(Node(n))else:tmpTree.append(None)root = tmpTree[0]# 2、转换为链式存储parent, child = 0, 1while child < len(tmpTree):if tmpTree[parent] != None:  # 双亲节点有效性判断if tmpTree[child] != None:  # 左孩子节点有效性判断tmpTree[parent].left = tmpTree[child]child += 1if child < len(tmpTree) and tmpTree[child] != None:  # 左孩子节点存在且有效tmpTree[parent].right = tmpTree[child]child += 1parent += 1return rootclass Solution:def connect(self, root: Optional[Node]) -> Optional[Node]:# 情况1、树为空if root == None:return root# 情况2、树不为空que = deque()que.append(root)while len(que) > 0:size = len(que)pre = Nonefor i in range(size):node = que.popleft()if i == 0:  # 记录每层第一个节点为prepre = nodeelse:  # 从每层第二个节点开始,都要给pre的next指针赋值pre.next = nodepre = nodeif node.left != None:que.append(node.left)if node.right != None:que.append(node.right)return rootif __name__ == "__main__":while True:try:in_line = input().strip().split('=')[1].strip()[1: -1]nums = []if in_line != '':for n in in_line.split(','):if n != 'null':nums.append(int(n))else:nums.append(n)print(nums)except EOFError:break

104. 二叉树的最大深度

一般 层序遍历的基础上,输出最大高度值,也就是二叉树的高度值

from typing import List, Optional, Union
from collections import deque
'''
104. 二叉树的最大深度
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例 1:输入:[3,9,20,null,null,15,7]输出:3
题眼:二叉树的层序遍历
思路:一般 层序遍历的基础上,输出最大高度值
'''class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef buildBinaryTree(nums: List[Union[int, str]]) -> Optional[TreeNode]:if len(nums) == 0:return Noneif len(nums) == 1:return TreeNode(nums[0])# 1、顺序存储tmpTree = []for n in nums:if n != 'null':tmpTree.append(TreeNode(n))else:tmpTree.append(None)root = tmpTree[0]# 2、链式存储parent, child = 0, 1while child < len(tmpTree):if tmpTree[parent] != None:  # 双亲结点有效if tmpTree[child] != None:  # 左孩子节点有效tmpTree[parent].left = tmpTree[child]child += 1  # 指向右孩子if child < len(tmpTree) and tmpTree[child] != None:  # 右孩子存在且有效tmpTree[parent].right = tmpTree[child]child += 1  # 指向下一个节点的左孩子parent += 1return rootclass Solution:def maxDepth(self, root: Optional[TreeNode]) -> int:# 情况1、树为空if root == None:return 0# 情况2、树不为空result = 0que = deque()que.append(root)while len(que) > 0:size = len(que)for _ in range(size):node = que.popleft()if node.left != None:que.append(node.left)if node.right != None:que.append(node.right)result += 1return result# 做完了计算完全二叉树的节点数,用了带return的递归法,有点感觉了,看看能否把这里的迭代法写出来def maxDepthRecursive(self, root: Optional[TreeNode]) -> int:# 1、确定函数参数和返回值def maxDepth(node: Optional[TreeNode]) -> int:# 2、终止条件if node == None:return 0# 3、单次递归的操作leftN = maxDepth(node.left)     # 左rightN = maxDepth(node.right)   # 右return max(leftN, rightN) + 1   # 中return maxDepth(root)if __name__ == "__main__":obj = Solution()while True:try:in_line = input().strip().split('=')[1].strip()[1: -1]nums = []if in_line != '':for n in in_line.split(','):if n != 'null':nums.append(int(n))else:nums.append(n)root = buildBinaryTree(nums)print(obj.maxDepth(root))except EOFError:break

111. 二叉树的最小深度

一般 层序遍历的基础上,输出最小高度值(第一次遍历到叶子节点的时候)

from typing import List, Optional, Union
from collections import deque
'''
111. 二叉树的最小深度
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
示例 1:输入:root = [3,9,20,null,null,15,7]输出:2
题眼:二叉树的层序遍历
思路:一般 层序遍历的基础上,输出最小高度值(第一次遍历到叶子节点的时候)
'''class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef buildBinaryTree(nums: List[Union[int, str]]) -> Optional[TreeNode]:if len(nums) == 0:return Noneif len(nums) == 1:return TreeNode(nums[0])# 1、顺序存储tmpTree = []for n in nums:if n != 'null':tmpTree.append(TreeNode(n))else:tmpTree.append(None)root = tmpTree[0]# 2、链式存储parent, child = 0, 1while child < len(tmpTree):if tmpTree[parent] != None:  # 双亲结点有效if tmpTree[child] != None:  # 左孩子节点有效tmpTree[parent].left = tmpTree[child]child += 1  # 指向右孩子if child < len(tmpTree) and tmpTree[child] != None:  # 右孩子存在且有效tmpTree[parent].right = tmpTree[child]child += 1  # 指向下一个节点的左孩子parent += 1return rootclass Solution:def minDepth(self, root: Optional[TreeNode]) -> int:# 情况1、树为空if root == None:return 0# 情况2、树不为空result = 0que = deque()que.append(root)while len(que) > 0:size = len(que)for _ in range(size):node = que.popleft()if node.left == None and node.right == None:return result + 1if node.left != None:que.append(node.left)if node.right != None:que.append(node.right)result += 1return result# 做完了最大深度的递归,试试这个最小深度的,有陷阱!!!def minDepthRecursive(self, root: Optional[TreeNode]) -> int:# 1、确定函数参数和返回值def minD(node: Optional[TreeNode]) -> int:# 2、终止条件if node == None:return 0# 3、单次递归的操作leftN = minD(node.left)                         # 左rightN = minD(node.right)                       # 右# 当一个左子树为空,右不为空,这时并不是最低点if node.left == None and node.right != None:    # 中return 1 + rightN# 当一个右子树为空,左不为空,这时并不是最低点if node.left != None and node.right == None:return 1 + leftNreturn min(leftN, rightN) + 1return minD(root)if __name__ == "__main__":obj = Solution()while True:try:in_line = input().strip().split('=')[1].strip()[1: -1]nums = []if in_line != '':for n in in_line.split(','):if n != 'null':nums.append(int(n))else:nums.append(n)root = buildBinaryTree(nums)print(obj.minDepth(root))except EOFError:break

559. N 叉树的最大深度

一般 层序遍历的基础上,遍历children部分

from typing import List, Optional, Union
from collections import deque
'''
559. N 叉树的最大深度
给定一个 N 叉树,找到其最大深度。
最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。
N 叉树输入按层序遍历序列化表示,每组子节点由空值分隔(请参见示例)。示例 1:输入:root = [1,null,3,2,4,null,5,6]输出:3
题眼:二叉树的层序遍历
思路:一般 层序遍历的基础上,遍历children部分
'''class Node:def __init__(self, val=None, children=None):self.val = valself.children = childrenclass Solution:def maxDepth(self, root: Optional[Node]) -> int:# 情况1、树为空if root == None:return 0# 情况2、树不为空result = 0que = deque()que.append(root)while len(que) > 0:size = len(que)for _ in range(size):node = que.popleft()if node.children != None:for child in node.children:que.append(child)result += 1return result

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/78747.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java的interface应用和面向接口编程

记录&#xff1a;477 场景&#xff1a;Java的关键字interface应用&#xff0c;一个接口&#xff0c;多个实现类。面向接口编程&#xff0c;把业务逻辑线提取出来作为接口&#xff0c;具体的业务实现通过该接口的实现类来完成。 版本&#xff1a;JDK 1.8。 1.一个Java接口 (…

自动化测试开发 —— 如何封装自动化测试框架?

封装自动化测试框架&#xff0c;测试人员不用关注框架的底层实现&#xff0c;根据指定的规则进行测试用例的创建、执行即可&#xff0c;这样就降低了自动化测试门槛&#xff0c;能解放出更多的人力去做更深入的测试工作。本篇文章就来介绍下&#xff0c;如何封装自动化测试框架…

不知道有用没用的Api

encodeURIComponent(https://www.baidu.com/?name啊啊啊) decodeURIComponent(https%3A%2F%2Fwww.baidu.com%2F%3Fname%3D%E5%95%8A%E5%95%8A%E5%95%8A) encodeURI(https://www.baidu.com/?name啊啊啊) decodeURI(https://www.baidu.com/?name%E5%95%8A%E5%95%8A%E5%95%8A) …

Mojo 语言官网

Mojo面向 AI 开发者的新型编程语言&#xff0c;无缝支持CPU、GPU&#xff0c;兼容Python&#xff0c;跟Python类似的语法&#xff0c;但是比Python快68000倍。目前Mojo仅支持Ubuntu&#xff0c;暂不支持Windows和Mac&#xff0c;可以在Mojo Playground先体验一下。 Mojo 语言…

Pytorch从零开始实战03

Pytorch从零开始实战——天气识别 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——天气识别环境准备数据集模型选择模型训练数据可视化总结 环境准备 本文基于Jupyter notebook&#xff0c;使用Python3.8&#xff0c;Pytorch2.0.1cu118&…

Linux 修改SSH的显示样式,修改终端shell显示的样式,美观更改

要修改SSH的显示样式&#xff0c;您可以使用自定义的PS1&#xff08;提示字符串1&#xff09;变量来更改命令行提示符的外观。在您的情况下&#xff0c;您想要的格式似乎包括日期和时间&#xff0c;以及当前目录。以下是一个示例PS1设置&#xff0c;可以实现您所描述的样式&…

【搭建私人图床】本地PHP搭建简单Imagewheel云图床,在外远程访问

文章目录 1.前言2. Imagewheel网站搭建2.1. Imagewheel下载和安装2.2. Imagewheel网页测试2.3.cpolar的安装和注册 3.本地网页发布3.1.Cpolar临时数据隧道3.2.Cpolar稳定隧道&#xff08;云端设置&#xff09;3.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 4.公网访问测…

静态内存与动态内存 malloc函数动态分配内存

动态内存 &#x1f338;栈和堆&#x1f338;静态内存的缺陷&#x1f338;malloc函数的使用&#x1f338;易混淆&#xff1a;静态内存与静态变量&#x1f338;malloc动态分配内存 &#x1f338;栈和堆 栈和堆都是计算机中常用的内存数据结构&#xff0c;两者各自的特点和优缺点…

【Spring面试】三、Bean的配置、线程安全、自动装配

文章目录 Q1、什么是Spring Bean&#xff1f;和对象有什么区别Q2、配置Bean有哪几种方式&#xff1f;Q3、Spring支持的Bean有哪几种作用域&#xff1f;Q4、单例Bean的优势是什么&#xff1f;Q5、Spring的Bean是线程安全的吗&#xff1f;Q6、Spring如何处理线程并发问题&#xf…

【已解决】您所使用的密钥ak有问题,不支持jsapi服务,可以访问该网址了解如何获取有效密钥。

您所使用的密钥ak有问题&#xff0c;不支持jsapi服务&#xff0c;可以访问该网址了解如何获取有效密钥。详情查看&#xff1a;http://lbsyun.baidu.com/apiconsole/key#。 问题 百度密钥过期 思路 注册成为开发者 如果还没注册百度地图api账号的&#xff0c;点击以后就进入…

【深度学习】 Python 和 NumPy 系列教程(廿二):Matplotlib详解:2、3d绘图类型(8)3D饼图(3D Pie Chart)

一、前言 Python是一种高级编程语言&#xff0c;由Guido van Rossum于1991年创建。它以简洁、易读的语法而闻名&#xff0c;并且具有强大的功能和广泛的应用领域。Python具有丰富的标准库和第三方库&#xff0c;可以用于开发各种类型的应用程序&#xff0c;包括Web开发、数据分…

WebRTC 源码 编译 iOS端

1. 获取依赖工具 首先&#xff0c;确保你已经安装了以下工具&#xff1a; GitDepot ToolsXcode&#xff08;确保已安装命令行工具&#xff09; 2. 下载 depot_tools 使用 git 克隆 depot_tools 并将其添加到你的 PATH 中&#xff1a; /path/to/depot_tools 替换为自己的路径…

unity C#客户端与服务器程序

客户端和服务器公共的脚本 OSC.cs // This is version 1.01(2015.05.27) // Tested in Unity 4 // Most of the code is based on a library for the Make Controller Kit1/* using UnityEngine; using System; using System.Collections; using System.Threading; using Syst…

Furion api npm web vue混合开发

Furion api npm web vue混合开发 Furion-api项目获取swagger.json文件复制json制作ts包删除非.ts文件上传到npm获取npm包引用 Furion-api项目获取swagger.json文件 使用所有接口合并的配置文件 复制json制作ts包 https://editor.swagger.io 得到 typescript-axios-clien…

【实用工具】Centos 安装ARL灯塔

文章目录 docker 安装安装docker-compose配置镜像加速器ARL安装和启动 docker 安装 yum install https://download.docker.com/linux/fedora/30/x86_64/stable/Packages/containerd.io-1.2.6-3.3.fc30.x86_64.rpm yum install docker-ce (若出现无法找到包可能是镜像源问题) 更…

怎么科学管理固定资产呢

在当今的商业环境中&#xff0c;固定资产的管理是企业成功的关键因素之一。然而&#xff0c;传统的固定资产管理方法往往过于繁琐&#xff0c;缺乏创新&#xff0c;导致资源的浪费和效率的低下。因此&#xff0c;我们需要一种新的、更加科学的方法来管理我们的固定资产。本文将…

C++多线程的用法(包含线程池小项目)

一些小tips: 编译命令如下&#xff1a; g 7.thread_pool.cpp -lpthread 查看运行时间&#xff1a; time ./a.out 获得本进程的进程id&#xff1a; this_thread::get_id() 需要引入的库函数有&#xff1a; #include<thread> // 引入线程库 #include<mutex> //…

Ui自动化测试上传文件方法都在这里了 ~

前言 实施UI自动化测试的时候&#xff0c;经常会遇见上传文件的操作&#xff0c;那么对于上传文件你知道几种方法呢&#xff1f;今天我们就总结一下几种常用的上传文件的方法&#xff0c;并分析一下每个方法的优点和缺点以及哪种方法效率&#xff0c;稳定性更高 被测HTML代码…

结构型模式-享元模式

主要用于减少创建对象的数量&#xff0c;以减少内存占用和提高性能。这种类型的设计模式属于结构型模式&#xff0c;它提供了减少对象数量从而改善应用所需的对象结构的方式。 享元模式尝试重用现有的同类对象&#xff0c;如果未找到匹配的对象&#xff0c;则创建新对象。我们…

java并发编程 SynchronousQueue详解

文章目录 1 SynchronousQueue是什么2 核心属性详解3 核心方法详解3.1 transfer(E e, boolean timed, long nanos)3.1.1 TransferStack实现3.1.2 TransferQueue实现 3.2 外部方法3.2.1 put(E e)3.2.2 offer(E e)3.2.3 take()3.2.4 poll() 4 总结 java 并发编程系列文章目录 1 S…