剑指offer系列之树(p61-63)
61. 二叉树的序列化和反序列化
题目描述
请实现两个函数,分别用来序列化和反序列化二叉树
思路
利用先序遍历的思想来实现序列化和反序列化。序列化就是将树转化为字符串保存起来,相邻结点之间用,
分隔,空结点使用#
表示;反序列化就是根据字符串还原二叉树。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:def __init__(self):self.index = -1def Serialize(self, root):# write code herestring = []def preOrder(p):if p == None:string.append('#,')else:string.append(str(p.val) + ',')preOrder(p.left)preOrder(p.right)preOrder(root)string = ''.join(string)return stringdef Deserialize(self, s):# write code hereself.index += 1sp = s.split(',')node = Noneif sp[self.index] != '#':node = TreeNode(int(sp[self.index]))node.left = self.Deserialize(s)node.right = self.Deserialize(s)return node
简化了一点:
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:def __init__(self):self.index = -1def Serialize(self, root):# write code hereif root == None:return '#,'return str(root.val) + ',' + self.Serialize(root.left) + self.Serialize(root.right)def Deserialize(self, s):# write code hereself.index += 1sp = s.split(',')node = Noneif sp[self.index] != '#':node = TreeNode(int(sp[self.index]))node.left = self.Deserialize(s)node.right = self.Deserialize(s)return node
62. 二叉搜索树的第kkk个结点
题目描述
给定一棵二叉搜索树,请找出其中的第kkk小的结点。例如,(5,3,7,2,4,6,8)(5,3,7,2,4,6,8)(5,3,7,2,4,6,8)中,按结点数值大小顺序第三小结点的值为4。
思路
思路一:中序遍历的递归算法
利用一个列表保存中序遍历的结果,时间复杂度为O(n)O(n)O(n),空间复杂度为O(logh+n),hO(logh+n),hO(logh+n),h为树的深度.
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:# 返回对应节点TreeNodedef KthNode(self, pRoot, k):# write code hereres = []def InOrder(root):if not root:return NoneInOrder(root.left)res.append(root)InOrder(root.right)InOrder(pRoot)return res[k - 1] if 0 < k <= len(res) else None
思路二:中序遍历的非递归算法
利用中序遍历的非递归算法。时间复杂度为O(n)O(n)O(n),空间复杂度为O(h),hO(h),hO(h),h为树的深度。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:# 返回对应节点TreeNodedef KthNode(self, pRoot, k):# write code herecount = 0if k <= count:return Nonep, stack = pRoot, []while p or len(stack) > 0:while p:stack.append(p)p = p.lefttmp = stack.pop(-1)count += 1if count == k:return tmpp = tmp.rightreturn None
63. 数据流中的中位数
题目描述
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
思路
思路一
每次插入时都把数据流调整为有序的,因此插入操作就相当于向有序数组中插入一个数,时间复杂度为O(n)O(n)O(n);取中位数时时间复杂度为O(1)O(1)O(1)。注意这里牛客网有个bug,GetMedian
函数必须多加一个任意参数才能通过。
class Solution:def __init__(self):self.data = []def Insert(self, num):if len(self.data) == 0:self.data.append(num)else:i = 0# 找到num应该被插入的位置while i < len(self.data) and self.data[i] < num:i += 1# num大于现存所有值if i == len(self.data):self.data.append(num)else:self.data.append(0)for j in range(len(self.data) - 2, i - 1, -1):self.data[j + 1] = self.data[j]self.data[i] = numdef GetMedian(self, damn): length = len(self.data) if length%2 == 1: return self.data[length//2] else: return (self.data[length//2] + self.data[length//2-1])/2.0
思路二
该思路相当于把有序数组分成两个部分,左边一部分使用大根堆存储,右边一部分用小根堆存储。只要能保证两个堆大小相差不超过1,就很容易利用两个堆获得中位数,此时两个堆的堆顶值就为中间的值。具体操作如下。
插入操作:
首先判断大根堆是否为空:
如果为空则直接插入;
若不为空,则使用堆顶元素和待插入元素比较大小,若前者更大,则说明待插元素应该是属于左半部分的,即应该插入大根堆;若后者更大,则说明应该插入到右半部分,即小根堆。每次插入后都进行堆调整操作。
插入操作完毕后,需要调整两个堆长度差不超过1,如果长度差超过了1则将更长的堆的堆顶元素弹出并压入到较短的堆中。这个步骤主要是为了方便取中位数。
取中位数:
根据两个堆的长度差情况取出中位数。注意这里取堆顶元素直接使用heap[0]
即可,不能使用heappop
,这样会导致数据流序列变化。
除此之外,需要注意的是,python
的堆默认为小根堆,因此对于大根堆的插入,要把数字乘以−1-1−1,这样才能保证堆顶元素的相反数是最大值。
# -*- coding:utf-8 -*-
import heapq
class Solution:def __init__(self):self.small_heap = []self.big_heap = []def Insert(self, num):# write code hereif len(self.big_heap) == 0:self.big_heap.append(-1 * num)elif num < self.big_heap[0] * -1:heapq.heappush(self.big_heap, -1 * num)else:heapq.heappush(self.small_heap, num)length_diff = len(self.big_heap) - len(self.small_heap)if length_diff > 1:tmp = heapq.heappop(self.big_heap)heapq.heappush(self.small_heap, -1 * tmp)elif length_diff < -1:tmp = heapq.heappop(self.small_heap)heapq.heappush(self.big_heap, -1 * tmp)def GetMedian(self, m):# write code herelength_diff = len(self.big_heap) - len(self.small_heap)if length_diff > 0:return -1 * self.big_heap[0]elif length_diff == 0:return (-1 * self.big_heap[0] + self.small_heap[0]) / 2.0else:return self.small_heap[0]
剑指offer系列之树(p61-63)相关推荐
- leetcode 打印_剑指 Offer 总结 - leetcode 剑指offer系列
剑指 Offer 系列完结撒花!! 本篇文章是对整个系列的精华总结, 对系列的每篇文章进行了分类, 并用一句话概括每道题的思路, 方便大家理解和记忆, 当然也包含原文完整链接供大家参考 总的来说, 写 ...
- 在要求输入数字处找到非数字字符_剑指 Offer 67. 把字符串转换成整数 leetcode 剑指offer系列...
点击专辑上方"蓝字"关注我吧 题目难度: 中等 原题链接[1] 今天继续更新剑指 offer 系列, 老样子晚上 6 点 45 分准时更新公众号 每日精选算法题, 大家记得关注哦~ ...
- 剑指offer python实现_剑指offer系列python实现 日更(三)
今天来讲讲斐波那契数列和它的孩子们~先讲个冷笑话:今天来一盘斐波那契炒饭,它等于昨天的炒饭加上前天的炒饭 7.斐波那契数列 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第 ...
- 数组中其余的排除_[leetcode 剑指offer系列] 面试题04. 二维数组中的查找
题目难度: 简单 原题链接 今天继续更新剑指 offer 系列, 这道题的优化空间非常大, 个人感觉很适合作为面试题, 值得一做. 大家在我的公众号"每日精选算法题"中的聊天框中回 ...
- 剑指offer系列-03.数组中的重复数字
剑指offer系列第03题.数组中的重复数字 找出数组中重复的数字.在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内. 数组中某些数字是重复的,但不知道有几个数字重复了,也不 ...
- 剑指offer系列-24.反转链表
剑指offer系列第24题.反转链表 题目描述: 定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点. 示例:输入: 1->2->3->4->5->N ...
- 剑指offer系列-06.从尾到头打印链表
剑指offer系列第06题.从尾到头打印链表 题目描述: 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 示例 1:输入:head = [1,3,2] 输出:[2,3,1] /* ...
- 剑指offer系列-30.包含min函数的栈
剑指offer系列第30题.包含min函数的栈 题目描述: 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中, 调用 min.push 及 pop 的时间复杂度都是 ...
- 剑指offer系列-09.用两个栈设计队列
剑指offer系列第09题.用两个栈设计队列 用两个栈实现一个队列.队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead , 分别完成在队列尾部插入整数和在队列头部删除整 ...
- 剑指offerpython_剑指offer系列python实现 日更(一)
写在开头,这个专栏是记录刷题/学习/求职面试的小号专栏.主要方向约等于是混口饭吃干啥都行,希望能够在学习的过程中有所输出,也能帮助到别人~ 废话少说,首先是经典的<剑指offer>系列,题 ...
最新文章
- Java项目开发全程实录pdf
- 用Matplotlib跟踪疫情实时监控2019-nCoV
- python 基础语法练习回顾
- html设置返回的样式,jQuery设置或返回元素样式属性。
- linux子线程运行的函数_Linux中线程使用详解
- 搭建gitlab及部署gitlab-runner
- Java SSM1——Maven
- 网上Silverlight项目收集
- 如何查看Tomcat版本信息
- 删好友警告,C语言最强整人小程序!(勿随便使用)
- Hello 2019(有待更新)
- Linux最基础知识整理
- 【转】支持向量机回归模型SVR
- java分组求和实例_mybatis example group by count 分组求和 - java分组求和
- excel查标准正态分布_利用Excel的NORMSDIST计算正态分布函数表
- 神经网络ANN——SPSS实现
- 计算机英语ppt答辩,计算机专业毕业论文答辩(英文)详解.ppt
- android 视频连续播放,VideoView实现视频无缝连续播放
- python 请假审批系统_请假审批系统
- 电脑的ppt打不开计算机二级,打不开电脑中的ppt文件并提示访问出错的解决方法...