前序、中序、后序遍历
class Solution:
def preorderTraversal(self , root: TreeNode) -> List[int]:
# write code here
if not root: return
result = []
def preorder(x):
if not x: return
result.append(x.val)
preorder(x.left)
preorder(x.right)
preorder(root)
return result
import sys
sys.setrecursionlimit(100000)
class Solution:
def inorderTraversal(self , root: TreeNode) -> List[int]:
# write code here
if not root: return
result = []
def inorder(x):
if not x: return
inorder(x.left)
result.append(x.val)
inorder(x.right)
inorder(root)
return result
class Solution:
def postorderTraversal(self , root: TreeNode) -> List[int]:
# write code here
if not root: return
result = []
def postorder(x):
if not x: return
postorder(x.left)
postorder(x.right)
result.append(x.val)
postorder(root)
return result
二叉树的层序遍历
class Solution:
def levelOrder(self , root: TreeNode) -> List[List[int]]:
# write code here
res = []
tree_list = []
if root == None:
return res
tree_list.append(root)
while len(tree_list) > 0:
level_number = len(tree_list)
tmp = []
for i in range(level_number):
# 记录每一层的节点个数
node = tree_list.pop(0)
tmp.append(node.val)
if node.left:
tree_list.append(node.left)
if node.right:
tree_list.append(node.right)
res.append(tmp)
return res
按之字形打印二叉树
class Solution:
def Print(self , pRoot: TreeNode) -> List[List[int]]:
# write code here
import collections
if not pRoot: return []
res, queue = [], collections.deque()
queue.append(pRoot)
count = 0
while queue:
tmp = []
for _ in range(len(queue)):
node = queue.popleft()
tmp.append(node.val)
if node.left: queue.append(node.left)
if node.right: queue.append(node.right)
count += 1
if count%2!=0:
res.append(tmp)
else:
res.append(tmp[::-1])
return res
二叉树的最大深度
class Solution:
def maxDepth(self , root: TreeNode) -> int:
# write code here
if not root: return 0
return max(self.maxDepth(root.left),self.maxDepth(root.right)) + 1
二叉树中和为某一值的路径
class Solution:
def hasPathSum(self , root: TreeNode, sum: int) -> bool:
# write code here
if not root:return False
if not root.left and not root.right and sum-root.val == 0:
return True
return self.hasPathSum(root.left,sum-root.val) or self.hasPathSum(root.right, sum-root.val)
二叉搜索树和双向链表
class Solution:
head = None
pre = None
def Convert(self , pRootOfTree ):
if not pRootOfTree:
# 中序递归,叶子为空则返回
return None
# 首先递归到最左最小值
self.Convert(pRootOfTree.left)
# 找到最小值,初始化head与pre
if not self.pre:
self.head = pRootOfTree
self.pre = pRootOfTree
# 当前节点与上一节点建立连接,将pre设置为当前值
else:
self.pre.right = pRootOfTree
pRootOfTree.left = self.pre
self.pre = pRootOfTree
self.Convert(pRootOfTree.right)
return self.head
对称的二叉树
class Solution:
def recursion(self, root1: TreeNode, root2: TreeNode):
# 可以两个都为空
if not root1 and not root2:
return True
# 只有一个为空或者节点值不同,必定不对称
if not root1 or not root2 or root1.val != root2.val:
return False
# 每层对应的节点进入递归
return self.recursion(root1.left, root2.right) and self.recursion(root1.right, root2.left)
def isSymmetrical(self , pRoot: TreeNode) -> bool:
return self.recursion(pRoot, pRoot)
class Solution:
def isSymmetrical(self , pRoot: TreeNode) -> bool:
temp1 = []
temp2 = []
temp = pRoot
def preorder(x):
if not x:
return
if not x.left or not x.right:
temp1.append(-1)
preorder(x.left)
temp1.append(x.val)
preorder(x.right)
def order(x):
if not x:
return
if not x.left or not x.right:
temp2.append(-1)
order(x.right)
temp2.append(x.val)
order(x.left)
preorder(pRoot)
order(temp)
print(temp1,temp2)
return True if temp1==temp2 else False
合并二叉树
【已知两颗二叉树,将它们合并成一颗二叉树。合并规则是:都存在的结点,就将结点值加起来,否则空的位置就由另一个树的结点来代替】
class Solution:
def mergeTrees(self , t1: TreeNode, t2: TreeNode) -> TreeNode:
# write code here
if not t1: return t2
if not t2: return t1
head = TreeNode(t1.val + t2.val)
head.left = self.mergeTrees(t1.left,t2.left)
head.right = self.mergeTrees(t1.right, t2.right)
return head
二叉树的镜像
class Solution:
def Mirror(self , pRoot: TreeNode) -> TreeNode:
# write code here
if not pRoot: return
head = TreeNode(pRoot.val)
head.left = self.Mirror(pRoot.right)
head.right = self.Mirror(pRoot.left)
return head
判断是不是二叉搜索树
class Solution:
def isValidBST(self , root: TreeNode) -> bool:
# write code here
temp = []
if not root:return
def inorder(x):
if not x:return
inorder(x.left)
temp.append(x.val)
inorder(x.right)
inorder(root)
return temp == sorted(temp)
判断是不是完全二叉树
class Solution:
def isCompleteTree(self , root: TreeNode) -> bool:
# write code here
nodes = [(root, 1)]
i = 0
while i < len(nodes):
node, v = nodes[i]
i += 1 # 计数当前是第几个节点
if node:
nodes.append((node.left, 2*v)) # 继续为左子节点编号
nodes.append((node.right, 2*v+1)) # 继续为右子节点编号
return nodes[-1][1] == i
判断是不是平衡二叉树
class Solution:
def IsBalanced_Solution(self , pRoot: TreeNode) -> bool:
# write code here
if not pRoot: return True
def depth(x):
if not x: return 0
return max(depth(x.left),depth(x.right)) + 1
return abs(depth(pRoot.left)-depth(pRoot.right))<=1 and self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right)
二叉搜索树的最近公共祖先
class Solution:
def lowestCommonAncestor(self , root: TreeNode, p: int, q: int) -> int:
# 空树找不到公共祖先
if not root:
return -1
# pq在该节点两边说明这就是最近公共祖先
if (p >= root.val and q <= root.val) or (p <= root.val and q >= root.val):
return root.val
# pq都在该节点的左边
elif p <= root.val and q <= root.val:
# 进入左子树
return self.lowestCommonAncestor(root.left, p, q)
#pq都在该节点的右边
else:
# 进入右子树
return self.lowestCommonAncestor(root.right, p, q)
在二叉树中找到两个节点的最近公共祖先
class Solution:
def lowestCommonAncestor(self , root: TreeNode, o1: int, o2: int) -> int:
# 该子树没找到,返回-1
if not root:
return -1
# 该节点是其中某一个节点
if root.val == o1 or root.val == o2:
return root.val
# 左子树寻找公共祖先
left = self.lowestCommonAncestor(root.left, o1, o2)
# 右子树寻找公共祖先
right = self.lowestCommonAncestor(root.right, o1, o2)
# 左子树为没找到,则在右子树中
if left == -1:
return right
# 右子树没找到,则在左子树中
if right == -1:
return left
# 否则是当前节点
return root.val
class Solution(object):
def lowestCommonAncestor(self, root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
if not root:return False
if root == p or root == q:
return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
if not left:
return right
if not right:
return left
return root
class Solution(object):
def lowestCommonAncestor(self, root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
# 如果当前节点的值 node.val 大于 p 和 q 的值,那证明 p 和 q 在 node 的左子树中
if root.val > p.val and root.val > q.val:
# 遍历左子树
return self.lowestCommonAncestor(root.left, p, q)
# 如果当前节点的值 node.val 小于 p 和 q 的值,那证明 p 和 q 在 node 的右子树中
if root.val < p.val and root.val < q.val:
# 遍历右子树
return self.lowestCommonAncestor(root.right, p, q)
# 如果当前节点的值 node.val 在 [p, q] 之间,那 node 就是最近公共祖先。
return root
序列化二叉树
class Solution:
str1 = []
def Serialize(self, root):
# write code here
if root == None:
self.str1.append("#")
return self.str1
self.str1.append(str(root.val))
self.Serialize(root.left)
self.Serialize(root.right)
return self.str1
start=-1
def Deserialize(self, s):
# write code here
self.start=self.start+1;
if self.start>=len(s) or s[self.start]=="#" or s==None :return ;
cur=TreeNode(int(s[self.start]))
cur.left=self.Deserialize(s)
cur.right=self.Deserialize(s)
return cur
重建二叉树
【给定节点数为 n 的二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点。
例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出如下图所示。】
class Solution:
def reConstructBinaryTree(self , pre: List[int], vin: List[int]) -> TreeNode:
n = len(pre)
m = len(vin)
# 每个遍历都不能为0
if n == 0 or m == 0:
return None
# 构建根节点
root = TreeNode(pre[0])
for i in range(len(vin)):
# 找到中序遍历中的前序第一个元素
if pre[0] == vin[i]:
# 左子树的前序遍历
leftpre = pre[1:i+1]
# 左子树的中序遍历
leftvin = vin[:i]
# 构建左子树
root.left = self.reConstructBinaryTree(leftpre, leftvin)
# 右子树的前序遍历
rightpre = pre[i+1:]
# 右子树的中序遍历
rightvin = vin[i+1:]
# 构建右子树
root.right = self.reConstructBinaryTree(rightpre, rightvin)
break
return root
class Solution:
def reConstructBinaryTree(self , pre: List[int], vin: List[int]) -> TreeNode:
# write code here
if not pre or not vin:
return None
#构造根节点,寻找左右子树的分界线
root = TreeNode(pre[0])
n = vin.index(pre[0])
#构造左右子树,递归调用
root.left = self.reConstructBinaryTree(pre[1:n + 1], vin[:n])
root.right = self.reConstructBinaryTree(pre[n + 1:], vin[n + 1:])
#返回根节点
return root
输出二叉树的右视图
【请根据二叉树的前序遍历,中序遍历恢复二叉树,并打印出二叉树的右视图】
class Solution:
def solve(self , xianxu , zhongxu ):
# write code here
result = []
def dfs(p, i, level):
if not p:
return
if level >= len(result):
result.append(p[0])
else:
result[level] = p[0]
tmp = i.index(p[0])
dfs(p[1:tmp+1], i[0:tmp] , level+1)
dfs(p[tmp+1:], i[tmp+1:], level+1)
dfs(xianxu, zhongxu, 0)
return result
108. 将有序数组转换为二叉搜索树
给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。
高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 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 sortedArrayToBST(self, nums):
"""
:type nums: List[int]
:rtype: TreeNode
"""
def helper(left, right):
if left > right:
return None
# 总是选择中间位置左边的数字作为根节点
mid = (left + right) // 2
root = TreeNode(nums[mid])
root.left = helper(left, mid - 1)
root.right = helper(mid + 1, right)
return root
return helper(0, len(nums) - 1)
二叉树的右视图
【给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。】
# 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 []
# 分别取左子树和右子树的右视图
left = self.rightSideView(root.left)
right = self.rightSideView(root.right)
# 如果右子树的右视图大,则返回[root.val] + right
if len(left) <= len(right):
return [root.val] + right
# 否则,返回左子树左视图多余的部分加右子树右视图加root.val
else:
return [root.val] + right + left[len(right):]