Leetcode刷题记录101-110,python语言
101 对称二叉树 (递归)
我们可以使用递归方法来解决这个问题,比较当前节点的左右子树是否镜像对称。递归终止条件是两个节点都为None,或者其中有一个节点为None。如果两个节点都非空,且值相等,则继续比较两个节点的左右子节点。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
if not root: # 根节点为空,true
return True
def isMirror(node1, node2): # 定义递归函数
if not node1 and not node2: # 判断镜像,当两个子节点都为空,true
return True
if not node1 or not node2: # 其中一个为空,false
return False
if node1.val != node2.val: # 两个不为空,值都不一样
return False
return isMirror(node1.left, node2.right) and isMirror(node1.right, node2.left) # and连接,两个子节点的左节点和右节点,对称对比
return isMirror(root, root)
102 二叉树的层序遍历(队列queue)
使用队列来实现层序遍历,从根节点开始将每一层的节点依次加入队列,并按照顺序弹出节点。同时,我们需要记录每个节点的层级信息,以便将它们归类到不同的列表中。以上代码中,我们首先定义了一个树节点类TreeNode,然后编写了levelOrder函数来实现二叉树的层序遍历。在循环中,我们按层级处理节点,并将它们添加到结果列表中。最后,我们创建了一棵测试用的二叉树,并输出结果。
参考https://blog.csdn.net/Colorful___/article/details/133603913
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
if not root:
return []
result = []
queue = [root] # 保存当前层的各个节点。初始化根节点在队列中,先进先出。和栈stack叠盘子 先进后出 后进先出 不一样
while queue: # 队列为真,
level_size = len(queue) # 队列多少个,当前层
current_level = [] # 当前层 为空;小list
for _ in range(level_size): # 当前层循环,进行加入到current_level小list里面,最后放入result
node = queue.pop(0) # pop(0)可以返回一个列表中的头一个元素, 弹出节点
current_level.append(node.val) # 当前层
if node.left: # 下一层的,先左子节点放入队列
queue.append(node.left)
if node.right: # 右子节点
queue.append(node.right)
result.append(current_level) # 将当前层的遍历加入result
return result
103 二叉树的锯齿形层序遍历 (队列queue)
这段代码包含一个 TreeNode 类来表示二叉树节点,和一个函数 zigzagLevelOrder 来执行锯齿形层序遍历。在主循环中,我们使用队列 queue 来迭代地处理每一层的节点,并且用 level 跟踪当前层数。我们还维护一个 result 列表,将每一层的值作为一个子列表添加到其中。
如果当前层级是奇数层,我们将该层的值反转后添加到 result 中,以实现锯齿形效果。最后返回 result 即可得到锯齿形层序遍历的结果。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
if not root:
return []
result = [] # 存储结果
level = 0 # 记录当前层,哪一层
queue = [root] # 初始队列,根节点;只放当前层的节点;先进先出,后进后出
while queue:
level_vals = [] # 存当前层所有节点的val值
next_level = [] # 找到下一层有哪些节点
for node in queue: # queue里是 当前层的所有节点,
level_vals.append(node.val)
if node.left: # 将下一层加入,next_level列表,先左子节点再右子节点
next_level.append(node.left)
if node.right:
next_level.append(node.right)
if level % 2 == 1: # 奇数层,;将当前层结果小list加入到result里面
result.append(level_vals[::-1]) # 从start到end,是倒着取值,step=-1这个意思,n n-1 n-2,。。。, 1,0;从右往左
else:
result.append(level_vals) # 偶数层 0 2 4
queue = next_level # 队列变为下一层的
level += 1
return result
104 二叉树的最大深度 (递归)
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
这段代码中,我们同样使用了 TreeNode 类来表示二叉树节点,并且定义了一个函数 maxDepth 来计算二叉树的最大深度。在这个递归函数中,如果当前节点为空,则返回深度为0。
然后我们递归地计算左子树和右子树的最大深度,分别存储在 left_depth 和 right_depth 中。函数最终返回左右子树深度的较大值加上1,代表当前节点及其子树的深度。
通过这种递归的方式,我们可以高效地计算出二叉树的最大深度。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
left_depth = self.maxDepth(root.left) # 假如这里root.left为空,这里一定返回0。或者就是返回max(left_depth, right_depth) + 1
right_depth = self.maxDepth(root.right)
return max(left_depth, right_depth) + 1
105 从前序与中序遍历序列构造二叉树 (递归)
在这段代码中,我们同样使用了 TreeNode 类来表示二叉树节点,并且定义了一个函数 buildTree 来根据前序遍历和中序遍历序列构建二叉树。
首先,我们检查前序遍历和中序遍历序列是否为空,如果有一个为空,就返回None。然后我们取前序遍历的第一个元素作为当前子树的根节点值,并创建对应的节点。
接着,我们在中序遍历中找到根节点的位置 root_idx,用它将中序遍历序列分成左子树和右子树两部分。根据 root_idx 分别递归构建左子树和右子树,通过切片操作得到左右子树的前序遍历和中序遍历序列。
最后,我们将左右子树连接到根节点上,并返回根节点,完成了从前序遍历和中序遍历序列构建二叉树的过程。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
if not preorder or not inorder: # 这里是or;有一个为空,就是返回none
return None
root_val = preorder[0]
root = TreeNode(root_val)
root_idx = inorder.index(root_val) # 中序遍历里面,根节点的index;因为根节点前面的都是左子树的节点,后面全是右子树节点。
#root_idx也表示 左子树的节点个数,有多少个,然后用在提取preorder里面的左子树序列list,即preorder[1:1+root_idx]包含了左子树所有的
root.left = self.buildTree(preorder[1:1+root_idx], inorder[:root_idx]) # 递归函数,输出 左子节点9,作为左子树的根节点。这个思路。前序中的左子树所有,中序中的左子树所有,作为buildtree函数输入数据。1:1+root_idx就是说取root_idx个节点出来,可以看到都是左子树的节点,个数满足
root.right = self.buildTree(preorder[1+root_idx:], inorder[root_idx+1:]) # 函数输出的,右子树的根节点20,右子节点
return root
法二,dfs,递归回溯
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
index = {x: i for i, x in enumerate(inorder)}
def dfs(pre_l, pre_r, in_l,in_r):
if pre_l == pre_r:
return None
root = TreeNode(preorder[pre_l])
left_size = index[preorder[pre_l]] - in_l # 左子树的大小
root.left = dfs(pre_l+1,pre_l+1+left_size,in_l,in_l+left_size)
root.right = dfs(pre_l+1+left_size,pre_r,in_l+1+left_size,in_r)
return root
return dfs(0,len(preorder), 0,len(inorder))
106 从中序与后序遍历序列构造二叉树 (递归)
后序遍历:先遍历一个节点的左子树,然后遍历其右子树,最后访问该节点本身
前序中序后序,就是说根节点的位置是在前,中间,最后,三种顺序,且都是先左子树,再右子树。
这段代码实现了根据中序遍历和后序遍历结果构造二叉树。主要思路是根据后序遍历的最后一个元素作为根节点,在中序遍历中找到对应位置,然后递归构建左子树和右子树。通过这种方式逐步构建整棵二叉树
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
if not inorder or not postorder:
return None
root_val = postorder[-1]
root = TreeNode(root_val)
root_index = inorder.index(root_val)
root.right = self.buildTree(inorder[root_index + 1:], postorder[root_index:-1]) # 右子树所有节点。postorder[root_index:-1]切片不包含最后一位。即去掉了根节点
root.left = self.buildTree(inorder[:root_index], postorder[:root_index]) # postorder[:root_index]表示把左子树节点个数作为了切片,取这么多个节点,其实就是所有左子树节点
return root
107 二叉树的层序遍历 II (队列queue)
在以上代码中,我们首先定义了TreeNode类来表示二叉树节点。然后定义了levelOrderBottom函数来实现自底向上的层次遍历。在levelOrderBottom函数中,我们使用队列queue来进行层次遍历,同时使用result列表来存储每一层的节点值。我们遍历每一层的节点时,将其值添加到level_vals列表中,并将下一层的节点添加到next_level列表中。最终,我们将level_vals添加到result中,并更新queue为next_level,以便继续下一层的遍历。最后,我们将result反转并返回,即得到了自底向上的层次遍历结果。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:
if not root:
return []
queue = [root] # 还是从根节点开始遍历。最后反转result[::-1]即可
result = [] # 储存多个小list,每层节点值
while queue:
level_vals = [] # 储存当前层的值
next_level = [] # 储存下一层节点
for node in queue: # 循环当前层所有节点
level_vals.append(node.val) # 值加入小list中
if node.left: # 先左子节点
next_level.append(node.left)
if node.right: # 再右子节点
next_level.append(node.right)
result.append(level_vals) # 将小list加入res
queue = next_level # 更新队列
return result[::-1]
108 将有序数组转换为二叉搜索树 (中间位置作为根节点,递归)
高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树
参考https://blog.csdn.net/youngyangyang04/article/details/109249461
在以上代码中,我们首先定义了TreeNode类来表示二叉树节点。然后定义了sortedArrayToBST函数来将排序好的数组转换为平衡的二叉搜索树。在sortedArrayToBST函数中,我们首先判断数组是否为空,如果为空,则返回None。然后找到数组的中间元素作为根节点的值,并创建根节点。接着,我们使用递归调用sortedArrayToBST函数来构造左子树和右子树,最终返回根节点。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
if not nums:
return None # 是none不是[],表示节点为空 none
mid = len(nums) // 2 # //表示除以2的整数除法;在除法运算时将结果向下舍入到最接近的整数
root = TreeNode(nums[mid])
root.left = self.sortedArrayToBST(nums[:mid]) # 函数输出左子树的根节点,即root的左子节点
root.right = self.sortedArrayToBST(nums[mid+1:])
return root
109 有序链表转换二叉搜索树(递归)
二叉搜索树的定义
二叉搜索树(Binary Search Tree)是一种特殊的二叉树,它满足以下性质:
左子树上的所有节点的值都小于根节点的值。
右子树上的所有节点的值都大于根节点的值。
它的左、右子树也分别是二叉搜索树
高度平衡二叉树是指一个二叉树每个节点的左右两个子树的高度差的绝对值不超过 1。
参考https://leetcode.cn/problems/convert-sorted-list-to-binary-search-tree/solutions/2436644/gong-shui-san-xie-jian-dan-di-gui-fen-zh-6t1x
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: # 同一个类class里面,用self调用函数即可
def sortedListToBST(self, head: Optional[ListNode]) -> Optional[TreeNode]:
n = 0
cur = head
#起始我们先对 head 进行一次遍历,得到链表长度 n, 也是数组nums的节点数量,联想108题找到中间节点
while cur:
n += 1
cur = cur.next
return self.build(head, 0, n - 1) # 0和n-1为左右指针的位置
def build(self, head: ListNode, l: int, r: int) -> TreeNode:
if l > r: # 这里是说n==1的情况,
return None
mid = l + r >> 1 # 找到中间位置,就是除2, l+r除以2 ;类似于l + r //2
t = mid - l # 偏移量,左指针到中间位置的间距
cur = head # 当前指针,头指针
while t > 0: # 有偏移量时,从head出发往前走t步,直到t==0
cur = cur.next
t -= 1
ans = TreeNode(cur.val) # 返回cur当前指针节点的值,作为二叉树的根节点
ans.left = self.build(head, l, mid - 1) # 左子树的递归,即返回ans根节点的左子节点.这里用head是因为head作为左子树的开头的节点,一直到mid-1位置的节点,都是左子树所有节点
ans.right = self.build(cur.next, mid + 1, r) # 函数输出右子节点
return ans
110 平衡二叉树 (递归)
一个平衡二叉树定义为:对于树中的每个节点,该节点的两个子树的深度差不超过1。
在以上代码中,我们首先定义了TreeNode类来表示二叉树节点。然后定义了isBalanced函数来判断给定的二叉树是否是平衡二叉树。在isBalanced函数中,我们使用内部函数checkHeight来递归地计算每个节点的左右子树的高度,并判断它们的高度差是否不超过1。如果高度差超过1,则返回-1;否则返回实际的高度。最终,我们通过判断根节点的高度是否不等于-1来确定整棵树是否是平衡二叉树。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isBalanced(self, root: Optional[TreeNode]) -> bool:
def checkHeight(node):
if not node:
return 0
left_height = checkHeight(node.left)
if left_height == -1: # 表示左子树不是平衡二叉树
return -1
right_height = checkHeight(node.right)
if right_height == -1:
return -1
if abs(left_height - right_height) > 1: # 这行是主要代码;表示此时已经不是平衡二叉树,返回-1
return -1
else:
return max(left_height, right_height) + 1 # 以当前节点为根节点的树的最大高度。返回二叉树的深度;-1表示已经不是平衡二叉树了,否则返回值为以该节点为根节点树的高度
return checkHeight(root) != -1 # 当checkHeight函数输出-1就是return false,说不是平衡二叉树