二叉树题目:
# 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: TreeNode) -> int:
if not root:return 0
return max(self.maxDepthhelper(root.left,1),self.maxDepthhelper(root.right,1))
def maxDepthhelper(self,node,d):
if node:
return max(self.maxDepthhelper(node.left,d+1),self.maxDepthhelper(node.right,d+1))
return d
更简便:
# 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: TreeNode) -> int:
if not root:return 0
return max(self.maxDepth(root.left),self.maxDepth(root.right))+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: TreeNode) -> bool:
self.result = True
self.maxdepth(root)
return self.result
def maxdepth(self,root):
if not root: return 0
l = self.maxdepth(root.left)
r = self.maxdepth(root.right)
if abs(l-r)>1:
self.result = False
return 1 +max(l,r)
# 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: TreeNode) -> bool:
return self.maxdepth(root) != -1
return self.result
def maxdepth(self,root):
if not root: return 0
l = self.maxdepth(root.left)
if l == -1: return -1
r = self.maxdepth(root.right)
if r == -1: return -1
return max(l,r)+1 if abs(l-r)<=1 else -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 diameterOfBinaryTree(self, root: TreeNode) -> int:
# 3个变量,左边深度,右边深度,本层的路径长度最大值
if not root: return 0
self.maxd = 0
self.maxdepth(root)
return self.maxd
def maxdepth(self,root):
if not root:
return 0
l = self.maxdepth(root.left)
r = self.maxdepth(root.right)
self.maxd = max(self.maxd,l+r)
return max(l,r)+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 invertTree(self, root: TreeNode) -> TreeNode:
if not root:
return
self.switchtree(root)
return root
def switchtree(self,root):
switchnode = root.right
root.right = root.left
root.left = switchnode
self.invertTree(root.right)
self.invertTree(root.left)
问题代码:
# 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 mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
root3 = TreeNode(0)
self.mergehelper(root1,root2,root3)
return root3
def mergehelper(self,root1,root2,root3):
if not root1 and root2:
return
elif not root1:
root3 = root2
elif not root2:
root3 = root1
else:
root3 = TreeNode(root1.val+root2.val)
self.mergehelper(root1.left,root2.left,root3.left)
self.mergehelper(root1.right,root2.right,root3.right)
问题:必须要存在这个节点,不能指向None之后给他赋值
循环用函数的套路:
return的东西刚好等于要改的地方
# 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 mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
if not root1 and not root2:
return None
elif not root1:
return root2
elif not root2:
return root1
else:
root3 = TreeNode(root1.val+root2.val)
root3.left = self.mergeTrees(root1.left,root2.left)
root3.right = self.mergeTrees(root1.right,root2.right)
return root3
# 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: TreeNode, targetSum: int) -> bool:
if not root:
return False
self.result = False
self.sumhelper(root,targetSum,root.val)
return self.result
def sumhelper(self,root,targetSum,sum1):
if not root.left and not root.right:
if sum1 == targetSum:
self.result = True
if root.left:
self.sumhelper(root.left,targetSum,sum1+root.left.val)
if root.right:
self.sumhelper(root.right,targetSum,sum1+root.right.val)
如果不调用新的函数的话,那么return的就是直接需要的结果
# 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: TreeNode, targetSum: int) -> bool:
if not root:
return False
if not root.left and not root.right:
return targetSum == root.val
return self.hasPathSum(root.left,targetSum-root.val) or self.hasPathSum(root.right,targetSum-root.val)
思路, 用一个list去存 进入递归的这个点到它不同的父节点的所有不同的值,然后判断sum是不是等于这个list里面的值,是的话加一
方法1:
class Solution:
def pathSum(self, root: TreeNode, sum: int) -> int:
self.sum = sum
self.count = 0
self.dfs(root,[])
return self.count
def dfs(self,root, sumlist):
if root is None:
return 0
sumlist = [num+root.val for num in sumlist]
sumlist.append(root.val)
for num in sumlist:
if num == self.sum:
self.count += 1
# count = sumlist.count(sum)
self.dfs(root.left,sumlist)
self.dfs(root.right, sumlist)
return的值要的就是计算出来的路径数量总和
dfs是O(n)的复杂度,子节点的深度平均O(logn)的话,数组生产的复杂度是O(logn)。总的时间复杂度就是O(nlogn)把
时间,O(N)
空间复杂度O(N^2)
方法2:
class Solution:
def pathSum(self, root: TreeNode, sum: int) -> int:
self.sum = sum
return self.dfs(root,[])
def dfs(self,root, sumlist):
if root is None:
return 0
sumlist = [num+root.val for num in sumlist]
sumlist.append(root.val)
count = 0
for num in sumlist:
if num == self.sum:
count += 1
# count = sumlist.count(sum)
return count + self.dfs(root.left, sumlist) + self.dfs(root.right, sumlist)
思路:用主函数去回溯主树的子树
一个函数去判断子树是不是和给的树相等
# 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 isSubtree(self, root: TreeNode, subRoot: TreeNode) -> bool:
"""
:type s: TreeNode
:type t: TreeNode
:rtype: bool
"""
if not root and not subRoot:
return True
if not root or not subRoot:
return False
return self.isSametree(root,subRoot) or self.isSubtree(root.left,subRoot) or self.isSubtree(root.right,subRoot)
def isSametree(self,s,t):
if not s and not t:
return True
if not s or not t:
return False
return s.val == t.val and self.isSametree(s.left,t.left) and self.isSametree(s.right,t.right)
# 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: TreeNode) -> bool:
if not root:
return True
return self.isSymmetrichelper(root.left,root.right)
def isSymmetrichelper(self,left,right):
if not left and not right:
return True
if not left or not right:
return False
return left.val == right.val and self.isSymmetrichelper(left.right,right.left) and self.isSymmetrichelper(left.left,right.right)
Pre-order 前序:根左右
In-order 中序: 左根右
Post-order 后序:左右根
注意叶子节点的定义:
叶子左右都没有子节点
# 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 minDepth(self, root: TreeNode) -> int:
self.depth = 100000
if not root:
return 0
return self.minDepthhelper(root,1)
def minDepthhelper(self,root,depth):
if not root.left and not root.right:
self.depth = depth
return depth
if depth > self.depth:
return depth
if not root.left:
return self.minDepthhelper(root.right,depth+1)
if not root.right:
return self.minDepthhelper(root.left,depth+1)
return min(self.minDepthhelper(root.left,depth+1),self.minDepthhelper(root.right,depth+1))
每次计算的时候一定要自己想例子按照代码肉眼debug一遍
# 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 sumOfLeftLeaves(self, root: TreeNode) -> int:
if not root:
return 0
if root.left:
if not root.left.left and not root.left.right:
return root.left.val + self.sumOfLeftLeaves(root.right)
return self.sumOfLeftLeaves(root.right) + self.sumOfLeftLeaves(root.left)
问题代码:
# 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 longestUnivaluePath(self, root: TreeNode) -> int:
self.ans = 0
self.maxrootpath(root)
return self.ans
def maxrootpath(self,root):
if not root:
return
left = self.maxrootpath(root.left)
right = self.maxrootpath(root.right)
left += 1 if root.left and root.left.val == root.val else 0
right += 1 if root.right and root.right.val == root.val else 0
self.ans = max(self.ans, left+right)
return left+right
问题:
1.
调用maxrootpath的时候left+right是计算出的经过当前根节点的最长路径
但return的值一定是经过当前节点的最深路径
2.
left = left + 1 if root.left and root.left.val == root.val else 0
right = right + 1 if root.right and root.right.val == root.val else 0
如果值不相等的话是直接置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 longestUnivaluePath(self, root: TreeNode) -> int:
self.ans = 0
self.maxrootpath(root)
return self.ans
def maxrootpath(self,root):
if not root:
return 0
left = self.maxrootpath(root.left)
right = self.maxrootpath(root.right)
left = left + 1 if root.left and root.left.val == root.val else 0
right = right + 1 if root.right and root.right.val == root.val else 0
self.ans = max(self.ans, left+right)
return max(left,right)
动态规划+二叉树
# 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 rob(self, root: TreeNode) -> int:
#动态规划,从下到上:
return max(self.robhelp(root))
def robhelp(self,root):
if not root: return 0,0 #偷,不偷
left = self.robhelp(root.left)
right = self.robhelp(root.right)
#偷当前节点,则子节点不能偷
v1 = root.val + left[1]+right[1]
#不偷当前节点,则取左右子树偷与不偷算下来的最大值加起来
v2 = max(left)+max(right)
return v1,v2
用一个set去存储值。
去掉最小值,剩下的那个就是第二小值
# 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
import heapq
class Solution:
def findSecondMinimumValue(self, root: TreeNode) -> int:
self.res = set()
if not root:
return -1
self.helper(root)
if len(self.res) < 2:
return -1
self.res.remove(min(self.res))
return min(self.res)
def helper(self,root):
if len(self.res) > 3:
return
if not root:
return
self.res.add(root.val)
self.helper(root.left)
self.helper(root.right)
# 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 averageOfLevels(self, root: TreeNode) -> List[float]:
self.sum = []
self.count = []
self.addlevel(root,0)
for i in range(len(self.sum)):
self.sum[i] = self.sum[i]/self.count[i]
return self.sum
def addlevel(self,pnode,level):
if not pnode:
return
if level < len(self.sum):
self.sum[level] += pnode.val
self.count[level] += 1
else:
self.sum.append(pnode.val)
self.count.append(1)
self.addlevel(pnode.left,level+1)
self.addlevel(pnode.right,level+1)