1.二叉树的最大深度
- 思路: 深度 = 层数—— 队列
- 代码链接
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def maxDepth(self, root):
"""
:type root: TreeNode
:rtype: int
"""
# 思路:最大深度,相当于层序遍历的层数
# 中序遍历用栈
# 层序遍历用队列
if not root: return 0
queue = collections.deque([root])
level = 0
while queue:
for i in range(len(queue)):
node = queue.popleft() # 先进先出
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
level += 1
return level
2.翻转二叉树
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def invertTree(self, root):
"""
:type root: TreeNode
:rtype: TreeNode
"""
# 1. 递归
if not root: return root # 注意这里的条件 如果root为空不能只返回[],而是要返回节点
# root.left, root.right = root.right, root.left
# self.invertTree(root.left)
# self.invertTree(root.right)
# return root
# 2. 栈 相当于前序遍历 中-左-右
stack = [root]
while stack:
node = stack.pop()
node.left, node.right = node.right, node.left
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
return root
3.对称二叉树
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def isSymmetric(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
if not root: return False # 如果是空子树 则其一定非轴对称
# 1.递归
# def compare(left, right):
# # 递归终止的条件
# if not left and not right: return True
# elif not left and right: return False
# elif left and not right: return False
# elif left.val != right.val:
# return False
# # 内外对比
# outside = compare(left.left, right.right)
# inside = compare(left.right, right.left)
# ans = outside and inside
# return ans
# # return outside == inside # 这样是错误的 应该判断两个是否都为True
# return compare(root.left, root.right)
# 2.迭代法 注意轴对称比较不需要对比根结点
left = root.left
right = root.right
# 左右子树同时对比 想到层序遍历——队列
queue = collections.deque()
queue.append(left)
queue.append(right)
while queue:
left = queue.popleft()
right = queue.popleft()
if not left and not right: continue # 如果左右子树都空的话,可以先跳过
if not left or not right or left.val != right.val: return False
# 队列添加的顺序等于想要比较的顺序
queue.append(left.left)
queue.append(right.right)
queue.append(left.right)
queue.append(right.left)
return True
4.二叉树的直径
- 代码链接
- 注意的是递归返回值和结果值的关系!
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def __init__(self):
self.ans = 1 # 表示节点数
def diameterOfBinaryTree(self, root):
"""
:type root: TreeNode
:rtype: int
"""
# 思路:长度为 该路径经过的结点数-1
self.depth(root)
return self.ans - 1
def depth(self, node):
if not node:
return 0
# 左子树的深度(经过的结点数)
L = self.depth(node.left)
R = self.depth(node.right)
self.ans = max(self.ans, L + R + 1) # 经过的节点数要加上自己本身
return max(L, R) + 1 # 递归返回左右子树的深度
4.二叉树的层序遍历
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def levelOrder(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
if not root: return root # 注意树的题目都需要对空树进行处理
queue = collections.deque([root])
res = []
while queue:
level = []
for i in range(len(queue)):
node = queue.popleft()
level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(level)
return res
5.将有序数组转换为二叉搜索树
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def sortedArrayToBST(self, nums):
"""
:type nums: List[int]
:rtype: TreeNode
"""
# 思路:找出根结点
if not nums: return None
mid = len(nums) / 2
node = TreeNode(val = nums[mid])
node.left = self.sortedArrayToBST(nums[0: mid])
node.right = self.sortedArrayToBST(nums[mid + 1:])
return node
6.验证二叉搜索树
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def __init__(self):
self.maxVal = float("-inf")
def isValidBST(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
# 中序遍历整个数组是递增的 左-中-右
if not root: return True # 空子树也是二叉搜索树
left = self.isValidBST(root.left)
# 注意值是递增的,则maxVal是慢慢变大的,如果当前节点比之前的最大值都小即错误
if root.val <= self.maxVal:
return False
self.maxVal = root.val
right = self.isValidBST(root.right)
return left and right
7.二叉搜索树中第k小的元素
- 代码链接
- 时间复杂度 o(n)
- 空间复杂度 o(n)
- 栈的深度:在最坏的情况下,栈的深度可以达到树的高度h,对于平均情况,二叉搜索树的高度为O(log n)(平衡树),而在最坏的情况下(例如退化成链表),树的高度为O(n)。
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def kthSmallest(self, root, k):
"""
:type root: TreeNode
:type k: int
:rtype: int
"""
# 中序遍历 迭代法 —— 栈
if not root: return root
stack = []
while stack or root:
while root:
stack.append(root)
root = root.left
root = stack.pop()
k -= 1
if k == 0:
return root.val
root = root.right
# 中序遍历 左- 中-右
# 错误写法 这是前序
# node = stack.pop()
# k -= 1
# if k == 0:
# return node.val
# if node.left:
# stack.append(node.left)
# if node.right:
# stack.append(node.right)
8.二叉树的右视图
- 代码链接
- 时间复杂度:O(n)
空间复杂度:O(n)
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def rightSideView(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
# 思路 层序遍历中每一层最后的节点
if not root: return root
queue = deque([root])
res = []
while queue:
level = []
for i in range(len(queue)):
node = queue.popleft()
level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(level[-1])
return res
9.二叉树展开为列表
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def flatten(self, root):
"""
:type root: TreeNode
:rtype: None Do not return anything, modify root in-place instead.
"""
# 前序遍历取出列表后 再依次修改每个树节点的左右子节点
stack = []
tree = []
while stack or root:
while root:
tree.append(root)
stack.append(root)
root = root.left
root = stack.pop()
root = root.right
for i in range(1, len(tree)):
pre, cur = tree[i - 1], tree[i]
pre.left = None
pre.right = cur
10.从前序与中序遍历序列构造二叉树
- 代码链接
- 注意的是索引是怎么获得的
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def buildTree(self, preorder, inorder):
"""
:type preorder: List[int]
:type inorder: List[int]
:rtype: TreeNode
"""
# 思路:前序遍历 中 - 左 - 右
# 中序遍历 左 - 中 - 右
if not preorder: return None
root_val = preorder[0]
root = TreeNode(val = root_val)
root_idx = inorder.index(root_val) # 获取index
left_inorder = inorder[:root_idx]
right_inorder = inorder[root_idx + 1:]
left_preorder = preorder[1:len(left_inorder) + 1]
right_preorder = preorder[len(preorder) - len(right_inorder):] # 这样找到倒数的开始的节点
root.left = self.buildTree(left_preorder, left_inorder)
root.right = self.buildTree(right_preorder, right_inorder)
return root