剑指offer-二叉树
1. 平衡二叉树
输入一棵二叉树,判断该二叉树是否是平衡二叉树。
解:
要么是一颗空树,要么左右子树都是平衡二叉树且左右子树深度之差不超过1
1 # class TreeNode:
2 # def __init__(self, x):
3 # self.val = x
4 # self.left = None
5 # self.right = None
6 class Solution:
7 def IsBalanced_Solution(self, pRoot):
8 # write code here
9 if not pRoot:
10 return True
11 res = abs(self.getDepth(pRoot.left) - self.getDepth(pRoot.right))
12 if res <= 1 and self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right):
13 return True
14 return False
15
16 def getDepth(self, root):
17 if not root:
18 return 0
19 if not (root.left or root.right):
20 return 1
21 return max(self.getDepth(root.left), self.getDepth(root.right)) + 1
2. 二叉树的深度
输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
解:
层次遍历,bfs 实现
1 # class TreeNode:
2 # def __init__(self, x):
3 # self.val = x
4 # self.left = None
5 # self.right = None
6 class Solution:
7 def TreeDepth(self, pRoot):
8 # write code here
9 if not pRoot:
10 return 0
11 depth = 0
12 queue = [pRoot]
13 while queue:
14 tmp = []
15 for i in range(len(queue)):
16 node = queue.pop(0)
17 tmp.append(node.val)
18 if node.left:
19 queue.append(node.left)
20 if node.right:
21 queue.append(node.right)
22 if tmp:
23 depth += 1
24 return depth
dfs 实现,只需要记录深度即可,不用记录节点
1 # class TreeNode:
2 # def __init__(self, x):
3 # self.val = x
4 # self.left = None
5 # self.right = None
6 class Solution:
7 def TreeDepth(self, pRoot):
8 # write code here
9 if not pRoot:
10 return 0
11 self.depth = 0
12 def helper(node, level):
13 if not(node.left or node.right):
14 self.depth = max(self.depth, level)
15 return
16 if node.left:
17 helper(node.left, level+1)
18 if node.right:
19 helper(node.right, level+1)
20
21 helper(pRoot, 1)
22 return self.depth
3. 二叉树的下一个节点
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
解:
几种可能的情况考虑一下即可
1 # class TreeLinkNode:
2 # def __init__(self, x):
3 # self.val = x
4 # self.left = None
5 # self.right = None
6 # self.next = None
7 class Solution:
8 def GetNext(self, pNode):
9 # write code here
10 if not pNode:
11 return
12
13 # 如果当前节点有右子树,中序遍历的下一个节点是其右子树的最左节点
14 if pNode.right:
15 pRight = pNode.right
16 while pRight.left:
17 pRight = pRight.left
18 return pRight
19
20 # 如果当前节点没有右子树,但是当前节点是其父节点的左子节点,下一个节点是其父节点
21 if pNode.next and pNode.next.left == pNode:
22 return pNode.next
23
24 # 如果当前节点没有右子树,但是是其父节点的右子节点,则一直向上遍历,找到是其父节点的左子结点的pNode
25 # 当前节点的下一个节点就是pNode的父节点
26 if pNode.next and pNode.next.right == pNode:
27 while pNode.next and pNode != pNode.next.left:
28 pNode = pNode.next
29 return pNode.next
30 return
4. 对称的二叉树
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
解:
递归实现,判断给定两个节点为根的子树是否镜像,首先根节点的值要相等,其次A的左子树和B的右子树、A的右子树和B的左子树要递归的进行判断
1 # class TreeNode:
2 # def __init__(self, x):
3 # self.val = x
4 # self.left = None
5 # self.right = None
6 class Solution:
7 def isSymmetrical(self, pRoot):
8 # write code here
9 if not pRoot:
10 return True
11 return self.compare(pRoot.left, pRoot.right)
12
13 def compare(self, p1, p2):
14 if p1 == None :
15 return p2 == None
16 if p2 == None:
17 return False
18 if p1.val != p2.val:
19 return False
20 return self.compare(p1.left, p2.right) and self.compare(p1.right, p2.left)
dfs,用栈实现,成对取出成对插入,镜像:左左配右右,左右配右左
1 # class TreeNode:
2 # def __init__(self, x):
3 # self.val = x
4 # self.left = None
5 # self.right = None
6 class Solution:
7 def isSymmetrical(self, pRoot):
8 # write code here
9 if not pRoot:
10 return True
11 stack = [pRoot.left, pRoot.right]
12
13 while stack:
14 right = stack.pop() # 成对取出
15 left = stack.pop()
16 if left == None and right == None:
17 continue
18 if left == None or right == None:
19 return False
20 if left.val != right.val:
21 return False
22
23 # 成对插入
24 stack.append(left.left)
25 stack.append(right.right)
26 stack.append(left.right)
27 stack.append(right.left)
28
29 return True
bfs,队列实现
1 # class TreeNode:
2 # def __init__(self, x):
3 # self.val = x
4 # self.left = None
5 # self.right = None
6 class Solution:
7 def isSymmetrical(self, pRoot):
8 # write code here
9 if not pRoot:
10 return True
11 queue = [pRoot.left, pRoot.right]
12
13 while queue:
14 left = queue.pop(0) # 成对取出
15 right = queue.pop(0)
16 if left == None and right == None:
17 continue
18 if left == None or right == None:
19 return False
20 if left.val != right.val:
21 return False
22
23 # 成对插入
24 queue.append(left.left)
25 queue.append(right.right)
26 queue.append(left.right)
27 queue.append(right.left)
28
29 return True
5. 把二叉树打印成多行
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
解:
层次遍历,bfs
1 # class TreeNode:
2 # def __init__(self, x):
3 # self.val = x
4 # self.left = None
5 # self.right = None
6 class Solution:
7 # 返回二维列表[[1,2],[4,5]]
8 def Print(self, pRoot):
9 # write code here
10 if not pRoot:
11 return []
12 res = []
13 queue = [pRoot]
14 while queue:
15 tmp = []
16 for i in range(len(queue)):
17 node = queue.pop(0)
18 tmp.append(node.val)
19 if node.left:
20 queue.append(node.left)
21 if node.right:
22 queue.append(node.right)
23 if tmp:
24 res.append(tmp)
25 return res
dfs
1 # class TreeNode:
2 # def __init__(self, x):
3 # self.val = x
4 # self.left = None
5 # self.right = None
6 class Solution:
7 # 返回二维列表[[1,2],[4,5]]
8 def Print(self, pRoot):
9 # write code here
10 if not pRoot:
11 return []
12 self.res = []
13
14 def helper(node, level):
15 if not node:
16 return
17 if level == len(self.res):
18 self.res.append([])
19 self.res[level].append(node.val)
20 if node.left:
21 helper(node.left, level + 1)
22 if node.right:
23 helper(node.right, level + 1)
24
25 helper(pRoot, 0)
26 return self.res
6. 按之字形顺序打印二叉树
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
解:
还是层次遍历,用一个 flag 控制每一层是正序还是逆序
1 # class TreeNode:
2 # def __init__(self, x):
3 # self.val = x
4 # self.left = None
5 # self.right = None
6 class Solution:
7 def Print(self, pRoot):
8 # write code here
9 if not pRoot:
10 return []
11 leftToRight = True
12 queue = [pRoot]
13 res = []
14 while queue:
15 tmp = []
16 for i in range(len(queue)):
17 node = queue.pop(0)
18 tmp.append(node.val)
19 if node.left:
20 queue.append(node.left)
21 if node.right:
22 queue.append(node.right)
23 if tmp:
24 if leftToRight:
25 res.append(tmp)
26 else:
27 res.append(tmp[::-1])
28 leftToRight = not leftToRight
29 return res
7. 序列化二叉树
二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
1 # class TreeNode:
2 # def __init__(self, x):
3 # self.val = x
4 # self.left = None
5 # self.right = None
6 class Solution:
7 def __init__(self):
8 self.flag = -1
9 def Serialize(self, root):
10 # write code here
11 if not root:
12 return '#!'
13 return str(root.val)+'!'+self.Serialize(root.left)+self.Serialize(root.right)
14
15 def Deserialize(self, s):
16 # write code here
17 self.flag += 1
18 vals = s.split('!')
19 if self.flag >= len(vals):
20 return None
21 root = None
22 if vals[self.flag] != '#':
23 root = TreeNode(int(vals[self.flag]))
24 root.left = self.Deserialize(s)
25 root.right = self.Deserialize(s)
26 return root
8. 二叉搜索树的第k个节点
给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。
解:
中序遍历即有序
1 # class TreeNode:
2 # def __init__(self, x):
3 # self.val = x
4 # self.left = None
5 # self.right = None
6 class Solution:
7 # 返回对应节点TreeNode
8 def KthNode(self, pRoot, k):
9 # write code here
10 if not pRoot:
11 return None
12 self.res = []
13 self.midOrdTrav(pRoot)
14 return self.res[k-1] if 0<k<=len(self.res) else None
15
16 def midOrdTrav(self, root):
17 if not root:
18 return
19 self.midOrdTrav(root.left)
20 self.res.append(root)
21 self.midOrdTrav(root.right)
中序遍历的时候维护一个计数器,到 k 个数了就返回
1 # class TreeNode:
2 # def __init__(self, x):
3 # self.val = x
4 # self.left = None
5 # self.right = None
6 class Solution:
7 # 返回对应节点TreeNode
8 def KthNode(self, pRoot, k):
9 # write code here
10 if not pRoot:
11 return None
12
13 count = 0
14 stack = []
15 p = pRoot
16 while p or stack:
17 while p:
18 stack.append(p)
19 p = p.left
20 if stack:
21 p = stack.pop()
22 count += 1
23 if count == k:
24 return p
25 p = p.right
26 return None
1 import heapq
2 class Solution:
3 def __init__(self):
4 self.small = [] # 小的数,大顶堆
5 self.large = [] # 大的数,小顶堆
6
7 def Insert(self, num):
8 # write code here
9 heapq.heappush(self.small, -heapq.heappushpop(self.large, num))
10 if len(self.large) < len(self.small):
11 heapq.heappush(self.large, -heapq.heappop(self.small))
12
13 def GetMedian(self, default=None):
14 # write code here
15 if len(self.large) > len(self.small):
16 return float(self.large[0])
17 return (self.large[0] - self.small[0])/2.
1 # class TreeNode:
2 # def __init__(self, x):
3 # self.val = x
4 # self.left = None
5 # self.right = None
6 class Solution:
7 # 返回构造的TreeNode根节点
8 def reConstructBinaryTree(self, pre, tin):
9 # write code here
10 if not pre or not tin:
11 return None
12 root = TreeNode(pre[0])
13 index = self.Search(tin, root.val) # tin.index(root.val)
14 root.left = self.reConstructBinaryTree(pre[1:index+1], tin[:index])
15 root.right = self.reConstructBinaryTree(pre[index+1:], tin[index+1:])
16 return root
17
18 def Search(self, nums, target):
19 if not nums:
20 return -1
21 n = len(nums)
22 for i in range(n):
23 if nums[i] == target:
24 return i
25 return -1
剑指offer-二叉树的更多相关文章
- 剑指Offer——二叉树
剑指Offer--二叉树 前言 数据结构通常是编程面试中考察的重点.在参加面试之前,应聘者需要熟练掌握链表.树.栈.队列和哈希表等数据结构,以及它们的操作.本片博文主要讲解二叉树操作的相关知识,主要包 ...
- 剑指offer 二叉树中和为某一个值的路径
剑指offer 牛客网 二叉树中和为某一个值的路径 # -*- coding: utf-8 -*- """ Created on Tue Apr 9 15:53:58 2 ...
- 剑指offer 二叉树的层序遍历
剑指offer 牛客网 二叉树的层序遍历 # -*- coding: utf-8 -*- """ Created on Tue Apr 9 09:33:16 2019 @ ...
- JS数据结构与算法 - 剑指offer二叉树算法题汇总
❗❗ 必看经验 在博主刷题期间,基本上是碰到一道二叉树就不会碰到一道就不会,有时候一个下午都在搞一道题,看别人解题思路就算能看懂,自己写就呵呵了.一气之下不刷了,改而先去把二叉树的基础算法给搞搞懂,然 ...
- 剑指offer——二叉树的镜像
题目:操作给定的二叉树,将其变换为源二叉树的镜像. 思路:前序(根左右的顺序)遍历一棵树,在存储的时候将其左右树进行交换,最后按照处理后的树还原,即得到其镜像. /** public class Tr ...
- 剑指Offer 二叉树中和为某一值的路径(dfs)
题目描述 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径. 思路: 递归,然后深搜,因为题目定义的, ...
- 剑指Offer 二叉树的镜像
题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10 6 / \ / \ ...
- 剑指Offer——二叉树的下一个结点
题目描述: 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 分析: 如果该结点存在右子树,那么返回右子树的最左结 ...
- 剑指Offer——二叉树的深度
题目描述: 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 分析: 二叉树的深度等于其左子树的深度和右子树的深度两个中最大的深 ...
- 剑指Offer——二叉树中和为某一值的路径
题目描述: 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径. 分析: 先序遍历二叉树,找到二叉树中结点值的和 ...
随机推荐
- 细说强网杯Web辅助
本文首发于“合天智汇”公众号 作者:Ch3ng 这里就借由强网杯的一道题目“Web辅助”,来讲讲从构造POP链,字符串逃逸到最后获取flag的过程 题目源码 index.php 获取我们传入的user ...
- 【JAVA】生成一个32位的随机数。防止重复,保留唯一性
作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985, QQ986945193 微博:http://weibo.com/mcxiaobing import ...
- light Map
Unity5中lightmap的坑 http://blog.csdn.net/langresser_king/article/details/48914901 Unity中光照贴图一二坑及解决办法 h ...
- POJ-2299-Ultra-QuickSort(单点更新 + 区间查询+离散化)
In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a seque ...
- UVA 11292-Dragon of Loowater (贪心)
Once upon a time, in the Kingdom of Loowater, a minor nuisance turned into a major problem. The shor ...
- oracle之二控制文件
控制文件 3.1 控制文件的功能和特点: 1)定义数据库当前物理状态,不断在往controlfile写入[SCN等] 2)维护数据的一致性 3)是一个二进制文件 ...
- USB 设备驱动(写给自己看的)
集线器与控制器(USB地址7bit) 设备,配置,端点,接口 USB1.0(低速1.2),1.1(全速450m),2.0(高速,电流传输)区别 引脚4根(V,D-,D+,gnd),miniUSB增加 ...
- [Leetcode]225. 用队列实现栈 、剑指 Offer 09. 用两个栈实现队列
##225. 用队列实现栈 如题 ###题解 在push时候搞点事情:push时入队1,在把队2的元素一个个入队1,再交换队2和队1,保持队1除pushguocheng 始终为空. ###代码 cla ...
- 阿里云服务器外网IP无法访问网站
1.添加IIS时添加了127.0.0.1的IP监听导致无法访问外网IP 添加IP监听:netsh http add iplisten 127.0.0.1显示IP监听:netsh http show i ...
- vim配置汇总
目录 配置行号 显示状态栏 设置提示换行线 配置行号 set number 效果 显示状态栏 set laststatus=2 设置提示换行线 set colorcolumn=81