系列文章目录
代码随想录算法训练营第一天|数组理论基础,704. 二分查找,27. 移除元素
代码随想录算法训练营第二天|977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II
代码随想录算法训练营第三天|链表理论基础,203.移除链表元素,707.设计链表,206.反转链表
代码随想录算法训练营第四天|24. 两两交换链表中的节点,19.删除链表的倒数第N个节点,面试题 02.07. 链表相交,142.环形链表II,总结
代码随想录算法训练营第五天|哈希表理论基础,242.有效的字母异位词,349. 两个数组的交集,202. 快乐数,1. 两数之和
代码随想录算法训练营第六天|454.四数相加II,383. 赎金信,15. 三数之和,18. 四数之和,总结
代码随想录算法训练营第七天|344.反转字符串,541. 反转字符串II,卡码网:54.替换数字,151.翻转字符串里的单词,卡码网:55.右旋转字符串
代码随想录算法训练营第八天|28. 实现 strStr(),459.重复的子字符串,字符串总结,双指针回顾
代码随想录算法训练营第九天|理论基础,232.用栈实现队列,225. 用队列实现栈
代码随想录算法训练营第十天|20. 有效的括号,1047. 删除字符串中的所有相邻重复项,150. 逆波兰表达式求值
代码随想录算法训练营第十一天|239. 滑动窗口最大值,347.前 K 个高频元素,总结
代码随想录算法训练营第十二天|理论基础,递归遍历,迭代遍历,统一迭代
代码随想录算法训练营第十三天|层序遍历10,226.翻转二叉树,101.对称二叉树
代码随想录算法训练营第十四天|104.二叉树的最大深度,559.n叉树的最大深度,111.二叉树的最小深度,222.完全二叉树的节点个数
代码随想录算法训练营第十五天|110.平衡二叉树,257. 二叉树的所有路径,404.左叶子之和
513.找树左下角的值
题目链接: 513.找树左下角的值
题目内容: 给定一个二叉树的根节点 root,请找出该二叉树的最底层最左边节点的值。假设二叉树中至少有一个节点。
视频讲解: 怎么找二叉树的左下角? 递归中又带回溯了,怎么办?| LeetCode:513.找树左下角的值
核心思想:遍历节点的同时保留层数,如果层数比之前得到的最大层数更大,则更新层数,当遍历到叶子节点时,返回当前节点的值即可。
# 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 findBottomLeftValue(self, root: Optional[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:
depth+=1
self.traversal(node.left,depth)
depth-=1
if node.right:
depth+=1
self.traversal(node.right,depth)
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
from collections import deque
class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
queue=deque()
queue.append(root)
result=0
while queue:
size = len(queue)
for i in range(size):
node=queue.popleft()
if i==0:
result=node.val
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return result
112.路径求和
题目链接: 112.路径求和
题目内容: 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。叶子节点 是指没有子节点的节点。
视频讲解: 拿不准的遍历顺序,搞不清的回溯过程,我太难了! | LeetCode:112.路径求和
class Solution:
def traversal(self, cur: TreeNode, count: int) -> bool:
if not cur.left and not cur.right and count == 0: # 遇到叶子节点,并且计数为0
return True
if not cur.left and not cur.right: # 遇到叶子节点直接返回
return False
if cur.left: # 左
count -= cur.left.val
if self.traversal(cur.left, count): # 递归,处理节点
return True
count += cur.left.val # 回溯,撤销处理结果
if cur.right: # 右
count -= cur.right.val
if self.traversal(cur.right, count): # 递归,处理节点
return True
count += cur.right.val # 回溯,撤销处理结果
return False
def hasPathSum(self, root: TreeNode, sum: int) -> bool:
if root is None:
return False
return self.traversal(root, sum - root.val)
113.路径求和ii
题目链接: 113.路径求和ii
题目内容: 给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。叶子节点 是指没有子节点的节点。
# 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 __init__(self):
self.result=[]
self.path=[]
def traversal(self,cur,count):
if not cur.left and not cur.right and count == 0:
self.result.append(self.path[:])
return
if not cur.left and not cur.right:
return
if cur.left:
self.path.append(cur.left.val)
count-=cur.left.val
self.traversal(cur.left,count)
count+=cur.left.val
self.path.pop()
if cur.right:
self.path.append(cur.right.val)
count-=cur.right.val
self.traversal(cur.right,count)
count+=cur.right.val
self.path.pop()
return
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
self.result.clear()
self.path.clear()
if not root:
return self.result
self.path.append(root.val)
self.traversal(root,targetSum-root.val)
return self.result
106.从中序与后序遍历序列构造二叉树
题目链接: 106.从中序与后序遍历序列构造二叉树
题目内容: 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
视频讲解: 坑很多!来看看你掉过几次坑 | LeetCode: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 postorder:
return None
#第二步:找当前的中间节点:后序遍历的最后一个
root_val=postorder[-1]
root=TreeNode(root_val)
#第三步:找分割点
separator_idx=inorder.index(root_val)
#第四步:分割inorder数组,得到左、右子树
inorder_left=inorder[:separator_idx]
inorder_right=inorder[separator_idx+1:]
#第五步:对照切割postorder数组
postorder_left=postorder[:len(inorder_left)]
postorder_right=postorder[len(inorder_left):len(postorder)-1]
#第六步:递归
root.left=self.buildTree(inorder_left,postorder_left)
root.right=self.buildTree(inorder_right,postorder_right)
#第七步:返回
return root
105.从前序与中序遍历序列构造二叉树
题目链接: 105.从前序与中序遍历序列构造二叉树
题目内容: 给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
# 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:
return None
#第二步:找当前的中间节点:前序遍历的第一个
root_val=preorder[0]
root=TreeNode(root_val)
#第三步:找分割点
separator_idx=inorder.index(root_val)
#第四步:分割inorder数组,得到左、右子树
inorder_left=inorder[:separator_idx]
inorder_right=inorder[separator_idx+1:]
#第五步:对照切割preorder数组
preorder_left=preorder[1:1+len(inorder_left)]
preorder_right=preorder[1+len(inorder_left):]
#第六步:递归
root.left=self.buildTree(preorder_left,inorder_left)
root.right=self.buildTree(preorder_right,inorder_right)
#第七步:返回
return root