到现在也无法自行写出二叉树的题…除了层序遍历,递归好容易错…
513.找树左下角的值
只能自发写出层序遍历,看见dfs就头疼,晕递归
# 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
deque = collections.deque([root])
res = []
depth = 0
while deque:
level = []
depth += 1
for i in range(len(deque)):
cur = deque.popleft()
level.append(cur.val)
if cur.left:
deque.append(cur.left)
if cur.right:
deque.append(cur.right)
res.append(level)
return res[depth-1][0]
递归容易错的是,在访问完左子树之后深度不回溯,这样会导致,访问完左子树访问右子树时,深度持续叠加,失去了深度的意义
# 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 = -1#深度不会小于0,因此随便定义一个负值作为初始值
depth = 0
self.res = 0
self.get_left(root,depth)#输入输出
return self.res
def get_left(self,root,depth):
if not root.left and not root.right:#到达叶子节点
if depth > self.max_depth:
self.max_depth = depth
self.res = root.val
return
if root.left:
depth += 1
self.get_left(root.left,depth)#如果在这层找到了叶子节点会直接return,没找到才会继续下一次循环
depth -= 1#因此需要将深度回溯到这个节点的父节点,而保持深度始终有意义
if root.right:
depth += 1
self.get_left(root.right,depth)
depth -= 1
前判断中间的点,在判断左右,前左右的顺序---->前序遍历
12. 路径总和
和257.求路径数、还有上面那道题一样的思路,前序遍历,线判断当前节点是否满足条件,满足则return 不满足则开找左右,同样找路的时候要做回溯。
卡哥还用了一个巧妙的思想是从根节点一个一个节点减下来,若差值==0,则证明找到了一条路。
# 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 hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if not root:
return False
return self.find_target(root,targetSum-root.val)
def find_target(self,root,count):#输入,当前节点+目前计数
#对当前节点的判断
if not root.left and not root.right:#是叶子节点
if count==0:#满足和等于目标值
return True
else :#不满足
return False
if root.left:
count -= root.left.val
if self.find_target(root.left,count):#有节点在前面的判断中返回了True
return True
count += root.left.val
if root.right:
count -= root.right.val
if self.find_target(root.right,count):
return True
count += root.right.val
return False
怎么好像有点开始上道了,但是单靠我自己似乎不太容易厘清逻辑
113.路径总和ii
深浅拷贝害我找了好久错误都不知道为什么
深拷贝:像这里用的这样,是copy当前path中存储的所有值,两种写法:path.copy()或者path[:]
浅拷贝:引用path存储的地址,那么这个值会随着path的改变而改变
所以如果要copy的对象在函数中始终在变化--->使用深拷贝,否则平常使用浅拷贝也可
# 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 pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
if not root:
return root
Spath = [root.val]
self.result = []
self.find_path(root,Spath,targetSum-root.val)
return self.result
def find_path(self,root,path,count):
if not root.left and not root.right:#这里只做判断,满足条件result就append
if count==0:
self.result.append(path.copy())#注意这里要用深拷贝-->copy副本,而不像之前一样
return
else:
return
if root.left:
path.append(root.left.val)
print(path)
count -= root.left.val
print(count)
# if self.find_path(root.left,path,count):#这里不再需要对递归的结果判断后再return了,结果已在判断那一部分做完
# self.result.append(path)
self.find_path(root.left,path,count)
count += root.left.val
path.pop()
if root.right:
path.append(root.right.val)
print(path)
count -= root.right.val
# if self.find_path(root.right,path,count):
# self.result.append(path)
self.find_path(root.right,path,count)
count += root.right.val
path.pop()
106.从中序与后序遍历序列构造二叉树
暂跳,似乎一般不会考我二叉树,二刷来补