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)相关推荐

  1. leetcode 打印_剑指 Offer 总结 - leetcode 剑指offer系列

    剑指 Offer 系列完结撒花!! 本篇文章是对整个系列的精华总结, 对系列的每篇文章进行了分类, 并用一句话概括每道题的思路, 方便大家理解和记忆, 当然也包含原文完整链接供大家参考 总的来说, 写 ...

  2. 在要求输入数字处找到非数字字符_剑指 Offer 67. 把字符串转换成整数 leetcode 剑指offer系列...

    点击专辑上方"蓝字"关注我吧 题目难度: 中等 原题链接[1] 今天继续更新剑指 offer 系列, 老样子晚上 6 点 45 分准时更新公众号 每日精选算法题, 大家记得关注哦~ ...

  3. 剑指offer python实现_剑指offer系列python实现 日更(三)

    今天来讲讲斐波那契数列和它的孩子们~先讲个冷笑话:今天来一盘斐波那契炒饭,它等于昨天的炒饭加上前天的炒饭 ‍ 7.斐波那契数列 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第 ...

  4. 数组中其余的排除_[leetcode 剑指offer系列] 面试题04. 二维数组中的查找

    题目难度: 简单 原题链接 今天继续更新剑指 offer 系列, 这道题的优化空间非常大, 个人感觉很适合作为面试题, 值得一做. 大家在我的公众号"每日精选算法题"中的聊天框中回 ...

  5. 剑指offer系列-03.数组中的重复数字

    剑指offer系列第03题.数组中的重复数字 找出数组中重复的数字.在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内. 数组中某些数字是重复的,但不知道有几个数字重复了,也不 ...

  6. 剑指offer系列-24.反转链表

    剑指offer系列第24题.反转链表 题目描述: 定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点. 示例:输入: 1->2->3->4->5->N ...

  7. 剑指offer系列-06.从尾到头打印链表

    剑指offer系列第06题.从尾到头打印链表 题目描述: 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 示例 1:输入:head = [1,3,2] 输出:[2,3,1] /* ...

  8. 剑指offer系列-30.包含min函数的栈

    剑指offer系列第30题.包含min函数的栈 题目描述: 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中, 调用 min.push 及 pop 的时间复杂度都是 ...

  9. 剑指offer系列-09.用两个栈设计队列

    剑指offer系列第09题.用两个栈设计队列 用两个栈实现一个队列.队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead , 分别完成在队列尾部插入整数和在队列头部删除整 ...

  10. 剑指offerpython_剑指offer系列python实现 日更(一)

    写在开头,这个专栏是记录刷题/学习/求职面试的小号专栏.主要方向约等于是混口饭吃干啥都行,希望能够在学习的过程中有所输出,也能帮助到别人~ 废话少说,首先是经典的<剑指offer>系列,题 ...

最新文章

  1. Java项目开发全程实录pdf
  2. 用Matplotlib跟踪疫情实时监控2019-nCoV
  3. python 基础语法练习回顾
  4. html设置返回的样式,jQuery设置或返回元素样式属性。
  5. linux子线程运行的函数_Linux中线程使用详解
  6. 搭建gitlab及部署gitlab-runner
  7. Java SSM1——Maven
  8. 网上Silverlight项目收集
  9. 如何查看Tomcat版本信息
  10. 删好友警告,C语言最强整人小程序!(勿随便使用)
  11. Hello 2019(有待更新)
  12. Linux最基础知识整理
  13. 【转】支持向量机回归模型SVR
  14. java分组求和实例_mybatis example group by count 分组求和 - java分组求和
  15. excel查标准正态分布_利用Excel的NORMSDIST计算正态分布函数表
  16. 神经网络ANN——SPSS实现
  17. 计算机英语ppt答辩,计算机专业毕业论文答辩(英文)详解.ppt
  18. android 视频连续播放,VideoView实现视频无缝连续播放
  19. python 请假审批系统_请假审批系统
  20. 电脑的ppt打不开计算机二级,打不开电脑中的ppt文件并提示访问出错的解决方法...

热门文章

  1. 宜家开发中心东亚区完成在中国的全新升级;牙科巨头卡瓦集团上海创新卓越中心正式启动 | 美通企业日报...
  2. python中的“ --snip-- ”是什么
  3. 金庸武侠内功排行榜TOP10
  4. 推送流程(极光推送)
  5. Mybatis与JPA的优缺点
  6. Android系统源代码目录
  7. 光栅渲染器(二)画线
  8. 用户行为监控(Piwik)
  9. HTML空格符号 nbsp; ensp; emsp; 介绍以及实现中文对齐的方法
  10. 史蒂夫·保罗·乔布斯