leetcode之树

计划三年内刷完leetcode,目前已坚持每天刷,已完成150道,二刷总结的时候争取把做过的题目写一下博客,有算法上的疑惑,欢迎加我微信tiankongdecheng1讨论交流。生而为人,尤其是程序猿,太累了。。。
LeetCode树的题目集锦
对力扣上的树题目做一下记录,语言使用python实现
拖了好久想要写一下,但是太懒了,现在正在前往广州的路上,23个小时的路程正好显得没事干做一下总结

1 找公共祖先

1.1 剑指 Offer 68 - I. 二叉搜索树的最近公共祖先

题意是给出一个二叉搜索树和两个结点p,q,在树中查找最近的公共祖先
解题思路:
(1)首先,想可能的情况:p,q在根结点的左右两侧;p,q在根结点的左子树上;p,q在根结点的右子树上
(2)然后,根据这些可能的情况设计算法

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode')#递归法
    	if root.val > p.val and root.val > q.val:#p,q在根结点的左子树上
    		return self.lowestCommonAncestor(root.left,p,q)
    	if root.val < p.val and root.val < q.val:#p,q在根结点的右子树上
    		return self.lowestCommonAncestor(root.right,p,q)
    	return root#p,q在根结点的左右两侧
    	'''#迭代法
    	while root:
    		if root.val > p.val and root.val > q.val:
    			root = root.left
    		elif root.val < p.val and root.val < q.val:
    			root = root.right
    		else:
    			break
    	return root'''

1.2 剑指 Offer 68 - II. 二叉树的最近公共祖先

与题1.1的不同是在二叉树中查找最近的公共祖先,二叉树不再拥有搜索树的性质
解题思路:
1.首先,想出可能的几种情况:p,q在根结点的左右两侧;p,q在根结点的左子树上;p,q在根结点的右子树上
2.接下来,考虑返回值:
(1)root为空,返回root;
(2)root.val == p.val or root.val ==q.val,返回root

class Solution:
    def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
    if not root or root.val == p.val or root.val == q.val:
    	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

2 打印二叉树

2.1 剑指 Offer 32 - I. 从上到下打印二叉树

从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/
9 20
/
15 7
返回:
[3,9,20,15,7]

class Solution:
    def levelOrder(self, root: TreeNode) -> List[int]:
    	if not root:
    		return []
    	res = []
    	que = collections.deque()
    	que.append(root)
    	while que:
    		s = que.popleft()
    		res.append(s.val)
    		if s.left:
    			que.append(s.left)
    		if s.right:
    			que.append(s.right)
    	return res    	

2.2 剑指 Offer 32 - II. 从上到下打印二叉树 II

从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/
9 20
/
15 7
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]

class Solution:
    def levelOrder(self, root: TreeNode) -> List[int]:
    	if not root:
    		return []
    	res = []
    	que = collections.deque()
    	que.append(root)
    	while que:
    		path = []
    		for i in range(len(que)):
    			s = que.popleft()
    			path.append(s.val)
    			if s.left:
    				que.append(s.left)
    			if s.right:
    				que.append(s.right)
    		res.append(path)
    	return res

2.3 剑指 Offer 32 - III. 从上到下打印二叉树 III

请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。

例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/
9 20
/
15 7
返回其层次遍历结果:
[
[3],
[20,9],
[15,7]
]
解题思路:这道题跟1.4一样,只要判断一下奇偶即可

class Solution:
    def levelOrder(self, root: TreeNode) -> List[int]:
    	if not root:
    		return []
    	res = []
    	que = collections.deque()
    	que.append(root)
    	while que:
    		path = []
    		for i in range(len(que)):
    			s = que.popleft()
    			if len(res)%2 == 0:
    				path.append(s.val)
    			else:
    				path.insert(0,s.val)
    			if s.left:
    				que.append(s.left)
    			if s.right:
    				que.append(s.right)
    		res.append(path)
    	return res

3 重构二叉树

3.1 105. 从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/
9 20
/
15 7
解题思路:遍历preorder,在inorder中寻找它的索引。根据索引固定左右子树的边界

class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
    dic = {}
    self.d = preorder
    fro i in range(len(preorder)):
    	dic[inorder[i]] = i
    def recur(preroot,l,r):
    	if left > right:
    		return 
    	root = TreeNode(self.d[preroot])
    	index = dic[preroot]
    	root.left = recur(preroot+1,left,index-1)
    	root.right = recur(preroot+1+index-left,index+1,right)
    	return root
    return recur(0,0,len(inorder)-1)
    	

3.2 106. 从中序与后序遍历序列构造二叉树

根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:
3
/
9 20
/
15 7
解题思路同3.1

class Solution:
    def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
    dic = {}
    self.d = postorder
    fro i in range(len(inorder)):
    	dic[inorder[i]] = i
    def recur(preroot,l,r):
    	if left > right:
    		return 
    	root = TreeNode(self.d[preroot])
    	index = dic[preroot]
    	root.left = recur(preroot-(right-index+1),left,index-1)
    	root.right = recur(preroot-1,index+1,right)
    	return root
    return recur(len(inorder)-1,0,len(inorder)-1) 

3.3

4 不同的二叉搜索树

尚未完结,不定期更新

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值