递归
- 二叉树的最大深度
思路:递归,没节点,返回0,有节点,返回1+max(l,r)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def maxDepth(self, root):
if not root:
return 0
return 1+max(self.maxDepth(root.left),self.maxDepth(root.right))
- 平衡二叉树
思路:求最大深度,判断abs(左子节点最大深度-右子节点最大深度)<=1 and 左子节点是否是平衡的 and 右子节点是否是平衡的。
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def isBalanced(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
if not root:
return True
return abs(self.maxDepth(root.right)-self.maxDepth(root.left))<=1 and self.isBalanced(root.left) and self.isBalanced(root.right)
def maxDepth(self, root):
if not root:
return 0
return 1+max(self.maxDepth(root.right),self.maxDepth(root.left))
- 二叉树的直径(最长路径是边的数目,不是节点的数目)
思路:算每个节点左边深度l=左节点深度+1,右边深度r=右节点深度+1,l+r和res对比取最大值。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def diameterOfBinaryTree(self, root: TreeNode) -> int:
res = 0
def dfs(root):
nonlocal res # 外部嵌套函数内的变量。
if not root:
return 0
l = dfs(root.left)
r = dfs(root.right)
res = max(res,l+r)
return 1+max(l,r)
dfs(root)
return res
- 翻转二叉树
思路:先把root.left和root.right调换位置,然后递归引用invertTree(root.left)和invertTree(root.right)
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def invertTree(self, root):
"""
:type root: TreeNode
:rtype: TreeNode
"""
if not root:
return
root.left,root.right = root.right,root.left
self.invertTree(root.left)
self.invertTree(root.right)
return root # return root别忘了。
- 合并二叉树
思路:都有值:t1 = t1+t2,都没有返回none,t1,t2只有一个,则返回一个。
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def mergeTrees(self, t1, t2):
"""
:type t1: TreeNode
:type t2: TreeNode
:rtype: TreeNode
"""
def dfs(t1,t2):
if not t1 or not t2:
return t1 if t1 else t2
t1.val += t2.val
t1.left = dfs(t1.left,t2.left)
t1.right = dfs(t1.right,t2.right)
return t1
return dfs(t1,t2)
- 路径总和(根到叶子节点路径和)
思路:not root:False.如果root.val==sum and not root.left and not root.right,true。
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def hasPathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: bool
"""
if not root:
return False
if root.val == sum and not root.left and not root.right:
return True
return self.hasPathSum(root.left, sum-root.val) or self.hasPathSum(root.right, sum-root.val)
- 路径总和 III(统计路径和等于一个数的路径数量)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def pathSum(self, root: TreeNode, sum: int) -> int:
def dfs(root, sumlist):
if not root:
return 0 # 这两句不要写在外面,递归函数里面是必须有这两句的
sumlist = [num+root.val for num in sumlist]
sumlist.append(root.val)
counts = sumlist.count(sum)
return counts + dfs(root.left, sumlist) + dfs(root.right, sumlist)
return dfs(root, []) # 而不是dfs(root, []),return counts
- 子树(检验 s 中是否包含 t )
思路:遍历(s,t),(s.left,t),(s.right,t)是否是isSubtree的树。再创建一个函数判断两个树是否isSametree。
# 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, s: TreeNode, t: TreeNode) -> bool:
if not s and not t:
return True
if not s or not t:
return False
return self.isSubtree(s.left,t) or self.isSubtree(s.right,t) or self.isSametree(s,t)
def isSametree(self,s,t):
if not s and not t:
return True
if not s or not t:
return False
if s.val != t.val:
return False
return self.isSametree(s.left,t.left) and self.isSametree(s.right,t.right)
- 对称二叉树
思路:先判定root,再创建个helper函数,输入l和r,判断l和r是否存在、相等,递归调用。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isSymmetric(self, root: TreeNode) -> bool:
if not root:
return True
def dfs(l,r):
if not l and not r:
return True
elif not l or not r:
return False
elif l.val != r.val: # 用3个if也是可以的。
return False
else:
return dfs(l.left,r.right) and dfs(r.left,l.right)
return dfs(root.left,root.right)
- 二叉树的最小深度
思路:dfs递归。not root:0, not root.left and not root.right: return 1, 都有:min(l,r),只存在一个就返回一个。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def minDepth(self, root: TreeNode) -> int:
if not root:
return 0
if root.left and root.right:
return 1+min(self.minDepth(root.left),self.minDepth(root.right))
elif root.left:
return 1+self.minDepth(root.left)
elif root.right:
return 1+self.minDepth(root.right)
else:
return 1
- 统计左叶子节点的和(计算给定二叉树的所有左叶子之和)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def sumOfLeftLeaves(self, root: TreeNode) -> int:
if not root:
return 0
if root.left and not root.left.left and not root.left.right:
return root.left.val+self.sumOfLeftLeaves(root.right)
else:
return self.sumOfLeftLeaves(root.left)+self.sumOfLeftLeaves(root.right)
- 相同节点值的最大路径长度(边数)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def longestUnivaluePath(self, root: TreeNode) -> int:
res = 0
def dfs(root):
if not root: return 0
nonlocal res
l_length = dfs(root.left)
r_length = dfs(root.right)
l = r = 0
if root.left and root.left.val == root.val:
l = l_length + 1
if root.right and root.right.val == root.val:
r = r_length + 1
res = max(res, l + r)
return max(l, r)
dfs(root)
return res
- 间隔遍历(打家劫舍 III)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def rob(self, root: TreeNode) -> int:
def dfs(root):
if not root:
return [0,0]
l = dfs(root.left)
r = dfs(root.right)
return [max(l[0],l[1])+max(r[0],r[1]), root.val+l[0]+r[0]] # [不偷,偷]。left[0]是root.left作为root,但不包括root.left下面的max(left)+max(right)
return max(dfs(root))
- 二叉树中第二小的节点 (输出所有节点中的第二小的值)(第二种方法也有点难理解)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def findSecondMinimumValue(self, root: TreeNode) -> int:
s = set()
def helper(root):
if not root:
return
s.add(root.val)
helper(root.left)
helper(root.right)
helper(root)
return sorted(s)[1] if len(s)>1 else -1
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def findSecondMinimumValue(self, root: TreeNode) -> int:
return self.helper(root,root.val)
def helper(self,root,value):
if not root:
return -1
if root.val>value:
return root.val
l=self.helper(root.left,value)
r=self.helper(root.right,value)
if l==-1:
return r
if r==-1:
return l
return min(r,l)
# 问题可以转化为求左右子树的最小值,如果左右子树最小值都大于根节点的值取较小的值。其他情况取左右子树较大的值。
层次遍历
16. 一棵树每层节点的平均数
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def averageOfLevels(self, root: TreeNode) -> List[float]:
if not root:
return []
cur_level = [root]
res = []
while cur_level:
res.append(sum(node.val for node in cur_level) / len(cur_level))
next_level = []
for node in cur_level:
if node.left:
next_level.append(node.left)
if node.right:
next_level.append(node.right)
cur_level = next_level
return res
- 得到左下角的节点(在树的最后一行找到最左边的值)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def findBottomLeftValue(self, root: TreeNode) -> int:
if not root:
return []
cur_level, res = [root], None
while cur_level:
next_level, res = [], cur_level[0].val
for node in cur_level:
if node.left:
next_level.append(node.left)
if node.right:
next_level.append(node.right)
cur_level = next_level
return res
前中后序遍历
18. 非递归实现二叉树的前序遍历
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
# 递归
res = []
def helper(root):
if not root:
return
res.append(root.val)
helper(root.left)
helper(root.right)
helper(root)
return res
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
# 迭代
res = []
if not root:
return res
stack = [root]
while stack:
node = stack.pop()
res.append(node.val)
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
return res
- 非递归实现二叉树的后序遍历
# 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 postorderTraversal(self, root: TreeNode) -> List[int]:
# 递归
res = []
def helper(root):
if not root:
return
helper(root.left)
helper(root.right)
res.append(root.val)
helper(root)
return res
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
# 迭代
res = []
if not root:
return res
stack = [root]
while stack:
node = stack.pop()
res.append(node.val)
if node.left :
stack.append(node.left)
if node.right:
stack.append(node.right)
return res[::-1]
- 非递归实现二叉树的中序遍历
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
# 递归
res = []
def helper(root):
if not root:
return
helper(root.left)
res.append(root.val)
helper(root.right)
helper(root)
return res
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
# 迭代
res = []
if not root:
return []
stack = []
cur = root
while stack or cur:
while cur:
stack.append(cur)
cur = cur.left
cur = stack.pop()
res.append(cur.val)
cur = cur.right
return res
9.6 16.21看完了
二叉查找树(BST):根节点大于等于左子树所有节点,小于等于右子树所有节点。
二叉查找树中序遍历有序。
BST
21. 修剪二叉查找树
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def trimBST(self, root: TreeNode, L: int, R: int) -> TreeNode:
if not root:
return
if root.val < L:
return self.trimBST(root.right,L,R)
if root.val > R:
return self.trimBST(root.left,L,R)
root.left = self.trimBST(root.left,L,R)
root.right = self.trimBST(root.right,L,R)
return root
- 二叉搜索树中第K小的元素
迭代
# 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 kthSmallest(self, root: TreeNode, k: int) -> int:
cur = root
stack = []
while cur or stack:
while cur:
stack.append(cur)
cur = cur.left
tmp = stack.pop()
k -= 1
if k == 0:
return tmp.val
if tmp.right:
cur = tmp.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 kthSmallest(self, root: TreeNode, k: int) -> int:
res = 0
def helper(root):
nonlocal k, res
if root.left:
helper(root.left)
k -= 1
if k == 0:
res = root.val
return
if root.right:
helper(root.right)
helper(root)
return res
- 把二叉查找树每个节点的值都加上比它大的节点的值
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def __init__(self):
self.total = 0
# 反序中序遍历。python2没有nonlocal,必须用def __init__(self):self.total = 0
def convertBST(self, root):
"""
:type root: TreeNode
:rtype: TreeNode
"""
def helper(root):
nonlocal total
if root:
helper(root.right)
self.total += root.val
root.val = self.total
helper(root.left)
return root
return helper(root)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def convertBST(self, root: TreeNode) -> TreeNode:
total = 0
def helper(root):
nonlocal total # python3可以用nonlocal.
if root: # 反序中序遍历
helper(root.right)
total += root.val
root.val = total
helper(root.left)
return root
return helper(root)
- 二叉查找树的最近公共祖先
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if p.val<root.val and q.val<root.val:
return self.lowestCommonAncestor(root.left,p,q)
if p.val>root.val and q.val>root.val:
return self.lowestCommonAncestor(root.right,p,q)
return root
- 二叉树的最近公共祖先
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
# 参考Krahets的题解。
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if not root or root == p or root == q:
return root
l = self.lowestCommonAncestor(root.left, p, q)
r = self.lowestCommonAncestor(root.right, p, q)
if not l:
return r
if not r:
return l
return root
- 从有序数组中构造二叉查找树
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
def helper(l, r): # 中序遍历:始终选择中间位置左边元素作为根节点
if l > r:
return
mid = l + (r - l) // 2
root = TreeNode(nums[mid])
root.left = helper(l, mid-1)
root.right = helper(mid+1, r) # 验证过,没错的。就是l<r时什么都不返回。
return root
return helper(0, len(nums)-1)
- 根据有序链表构造平衡的二叉查找树
# 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:
def sortedListToBST(self, head: ListNode) -> TreeNode:
def findmid(head, tail):
slow = head
fast = head
while fast != tail and fast.next!= tail:
slow = slow.next
fast = fast.next.next
return slow
def helper(head, tail):
if head == tail:
return
node = findmid(head, tail)
root = TreeNode(node.val)
root.left = helper(head, node) # 左边一半利用tail来作为末尾点,右边一半用none作为末尾点,好办法。
root.right = helper(node.next, tail)
return root
return helper(head, None)
- 在二叉查找树中寻找两个节点,使它们的和为一个给定值
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def findTarget(self, root: TreeNode, k: int) -> bool:
map_set = set()
stack = [root]
while stack:
node = stack.pop()
if node:
if k - node.val in map_set:
return True
else:
map_set.add(node.val)
stack.append(node.right)
stack.append(node.left)
return False
- 在二叉查找树中查找两个节点之差的最小绝对值
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def getMinimumDifference(self, root: TreeNode) -> int:
stack = []
node = root
pre = -float('inf')
min_val = float('inf')
while node or stack:
while node:
stack.append(node)
node = node.left
node = stack.pop()
cur = node.val
if cur - pre < min_val:
min_val = cur - pre
pre = cur
node = node.right
return min_val
- 寻找二叉查找树中出现次数最多的值
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def findMode(self, root: TreeNode) -> List[int]:
if not root:
return []
node = root
stack = []
res = []
max_times = 1
time = 1
pre = float("inf")
while node or stack:
while node:
stack.append(node)
node = node.left
node = stack.pop()
cur = node.val
if cur == pre:
time += 1
else:
time = 1
pre = cur
if time == max_times:
res.append(cur)
if time > max_times:
res = [cur]
max_times = time
node = node.right
return res
9.7看完了 9.10看完了,9.11看完了
Trie:又称前缀树或字典树,用于判断字符串是否存在或者是否具有某种字符串前缀。
31. 实现一个 Trie(没怎么看懂)
class Trie(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.d = {}
def insert(self, word):
"""
Inserts a word into the trie.
:type word: str
:rtype: None
"""
tree = self.d # 起别名,然后不断覆盖这个别名,对tree所有的操作都会在self.d上也操作一次
for a in word:
if a not in tree:
tree[a] = {}
tree = tree[a] # key是字符,value是字典,每个字典相当于树的节点,tree=tree[a]把指针移到下个字符的节点。
tree["#"] = "#"
def search(self, word):
"""
Returns if the word is in the trie.
:type word: str
:rtype: bool
"""
tree = self.d
for a in word:
if a not in tree:
return False
tree = tree[a]
if "#" in tree:
return True
return False
def startsWith(self, prefix):
"""
Returns if there is any word in the trie that starts with the given prefix.
:type prefix: str
:rtype: bool
"""
tree = self.d
for a in prefix:
if a not in tree:
return False
tree = tree[a]
return True
- 实现一个 Trie,用来求前缀和(没怎么看懂)
class MapSum:
def __init__(self):
self.d = {}
def insert(self, key: str, val: int) -> None:
tree = self.d
for c in key:
if c not in tree:
tree[c] = {}
tree = tree[c] # 字典迭代
tree['val'] = val # 迭代终点赋值
def sum(self, prefix: str) -> int:
tree = self.d
for c in prefix:
if c not in tree:
return 0 # 判断前缀是否存在
tree = tree[c]
res = 0
def dfs(tree):
for c in tree:
if c == 'val':
nonlocal res
res += tree[c] # 前缀求和
else:
dfs(tree[c])
dfs(tree)
return res
# Your MapSum object will be instantiated and called as such:
# obj = MapSum()
# obj.insert(key,val)
# param_2 = obj.sum(prefix)