513 找树左下角的值
层序遍历很简单
from collections import deque
class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
if not root: return None
que = deque([root])
ans = []
while len(que) != 0:
temp = []
for i in range(len(que)):
node = que.popleft()
if node.left: que.append(node.left)
if node.right: que.append(node.right)
temp.append(node.val)
ans.append(temp)
return ans[-1][0]
递归还是不太会写,看了解答写的
class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
self.maxDepth = float('-inf')
self.result = None
self.find(root,0)
return self.result
def find(self,node,depth):
if not node.left and not node.right:
if depth > self.maxDepth:
self.maxDepth = depth
self.result = node.val
return
if node.left:
depth += 1
self.find(node.left,depth)
depth -= 1
if node.right:
depth += 1
self.find(node.right,depth)
depth -= 1
注意,在python中,self的所有属性都可以视作公共变量,在任意函数中都可以定义这样的公共变量,并跨函数使用这些变量
甚至只要是函数外面定义的变量,基本都可以在函数内进行访问,但不能修改它的值,尝试修改会在函数内创建一个同名的变量修改,但self属性则可以在类内的所有函数中查看,修改,相当于使用global将其全局化之后的变量
float(‘inf’) 表示正无穷大
float(‘-inf’) 表示负无穷大
112 路径总和
暴力方法是遍历所有路径,并逐个判断是否等于目标,可以先用递归试着写一下这个思路
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if not root: return False
self.path = []
self.pathSet = []
self.enumeratePath(root)
for x in self.pathSet:
if sum(x) == targetSum:
return True
return False
def enumeratePath(self,node):
if (not node.left) and (not node.right):
self.path.append(node.val)
self.pathSet.append([x for x in self.path])
self.path.pop()
return
if node.left:
self.path.append(node.val)
self.enumeratePath(node.left)
self.path.pop()
if node.right:
self.path.append(node.val)
self.enumeratePath(node.right)
self.path.pop()
关于传值还是传地址一定要搞清楚
113 路经总和Ⅱ
上一题递归加个判断即可
class Solution:
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
if not root: return []
self.path = []
self.pathSet = []
self.targetSum = targetSum
self.findPaths(root)
return self.pathSet
def findPaths(self,node):
if not node.left and not node.right:
self.path.append(node.val)
if sum(self.path) == self.targetSum:
self.pathSet.append([x for x in self.path])
self.path.pop()
return
if node.left:
self.path.append(node.val)
self.findPaths(node.left)
self.path.pop()
if node.right:
self.path.append(node.val)
self.findPaths(node.right)
self.path.pop()
106 从中序与后序遍历序列构造二叉树
先从后序遍历最后一个找到根节点,以此来在中序遍历中区分左右子树,按此逻辑递归即可
尝试了一下实现了基本功能,可以通过测试算例,但是跑不通,忽略了一种在切割后某个子树为空的情况
看了解答比我要快一点,不用判断左右是否为空,直接在返回条件那里判断即可
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
root = self.create(inorder,postorder)
return root
def create(self,inorder,postorder):
if inorder == postorder and len(inorder) == 1:
node = TreeNode(val = inorder[0])
return node
rootIndex = inorder.index(postorder[-1])
node = TreeNode(val = inorder[rootIndex])
leftIn = inorder[:rootIndex]
lenLeft = len(leftIn)
leftPost = postorder[:lenLeft]
if lenLeft != 0:
node.left = self.create(leftIn,leftPost)
rightIn = inorder[rootIndex+1:]
lenRight = len(rightIn)
rightPost = postorder[lenLeft:lenLeft+lenRight]
if lenRight != 0:
node.right = self.create(rightIn,rightPost)
return node
debug后通过
105.从前序与中序遍历序列构造二叉树
一样的题,改一下顺序即可
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
if len(preorder) == 0:
return None
rootIndex = inorder.index(preorder[0])
node = TreeNode(val = preorder[0])
leftIn = inorder[:rootIndex]
lenLeft = len(leftIn)
leftPre = preorder[1:1+lenLeft]
node.left = self.buildTree(leftPre,leftIn)
rightIn = inorder[rootIndex+1:]
lenRight = len(rightIn)
rightPre = preorder[1+lenLeft:]
node.right = self.buildTree(rightPre,rightIn)
return node