1-1函数的渐进性

对于下面5个函数集合中每一个,对它们进行排序。如果在序列中, f a f_a fa​出现在 f b f_b fb​之前,那么 f a = O ( f b ) f_a=\mathcal{O}(f_b) fa​=O(fb​)。如果 f a = O ( f b ) f_a=\mathcal{O}(f_b) fa​=O(fb​)且 f b = O ( f a ) f_b=\mathcal{O}(f_a) fb​=O(fa​),意味着 f a f_a fa​和 f b f_b fb​可以任何顺序出现,可以用花括号把 f a 和 f b f_a和f_b fa​和fb​围起来表明这种情况。例如,如果多个函数为:

f 1 = n , f 2 = n , f 3 = n + n f_1=n,f_2=\sqrt{n},f_3=n+\sqrt{n} f1​=n,f2​=n ​,f3​=n+n ​

正确的答案是: ( f 2 , { f 1 , f 3 } ) 或 ( f 2 , { f 3 , f 1 } ) (f_2,\{ f_1 , f_3 \} )或(f_2,\{ f_3 , f_1 \} ) (f2​,{f1​,f3​})或(f2​,{f3​,f1​})

a) f 1 = ( l o g n ) 2019 , f 2 = n 2 l o g ( n 2019 ) , f 3 = n 3 , f 4 = 2.01 9 n , f 5 = n l o g n f_1=(logn)^{2019},f_2=n^2log(n^{2019}),f_3=n^3,f_4=2.019^n,f_5=nlogn f1​=(logn)2019,f2​=n2log(n2019),f3​=n3,f4​=2.019n,f5​=nlogn

f 1 , f 5 , f 2 , f 3 , f 4 f_1,f_5,f_2,f_3,f_4 f1​,f5​,f2​,f3​,f4​

b) f 1 = 2 n , f 2 = n 3 , f 3 = ( n n / 2 ) , f 4 = n ! , f 5 = ( n 3 ) f_1=2^n,f2=n^3,f_3=\binom{n}{n/2},f_4=n!,f_5=\binom{n}{3} f1​=2n,f2=n3,f3​=(n/2n​),f4​=n!,f5​=(3n​)

{ f 2 , f 5 } , f 3 , f 1 , f 4 \{f_2,f_5\},f_3,f_1,f_4 {f2​,f5​},f3​,f1​,f4​

1-2队列基本操作

给定一个数据结构D,支持4个 first/last 序列操作:

D.insert_first(x),D.delete_first(),D.insert_last(x),D.delete_last()

每个操作都是 O ( 1 ) \mathcal{O}(1) O(1),描述算法:用低级操作方法来实现下面高级操作。

删除操作返回删除的元素。

(a) swap_ends(D):以 O ( 1 ) \mathcal{O}(1) O(1)复杂度交换序列中第一个和最后一个元素。

first = D.delete_first()

end = D.delete_last()

D.insert_first(end)

D.insert_last(first)

(b)shift_left(D,k):以 O ( k ) \mathcal{O}(k) O(k)复杂度把前k个元素按顺序移动到序列末尾,移动完后,之前序列中的第k个元素成为末尾,之前序列中的第k+1个元素成为序列之首。

for(int i=0; i < k; i++) {

tmp = D.delete_first();

D.insert_last(tmp)

}

1-3双端队列操作

动态数组可以实现一个序列接口,支持最坏情形 O ( 1 ) \mathcal{O}(1) O(1)时间索引(根据角标i找到对应元素),以及从数组后面插入、删除item是可变常量时间(插入n个item,时间为 O ( n ) ) \mathcal{O}(n)) O(n))。然而在动态数组前面插入和删除,并非足够有效的,因为每个entry必须移动来保持序列所有entry的有序性,花费线性时间。

另一方面,链表数据结构,在两端都可以最坏情形 O ( 1 ) \mathcal{O}(1) O(1)支持插入、删除操作,但代价是线性时间查找。

我们可以两个好处都占:设计一个数据结构来存储一系列的item,支持最坏情形 O ( 1 ) \mathcal{O}(1) O(1)时间索引查找,以及可摊还 O ( 1 ) \mathcal{O}(1) O(1)时间在两端插入和删除。你的数据结构应该使用 O ( n ) \mathcal{O}(n) O(n)空间来存储n个item。

有多种可能的解法。一种解法:使用两个栈(stack)来实现dequeue(双端队列),需要关注的是:从空栈中弹出(pop),向满栈中压入(push)。一个可选择的方式是:将队列元素存储到数组中间,而不是前面,无论何时重建(rebuild),都在首尾留有线性数量的额外槽(slot),保证仅会每n次操作用线性时间重建(rebuild)。

例如,无论何时重新分配空间来存储n个元素(item),把它们拷贝到一个长度m=3n的数组中部。为了插入、删除一个序列头部、尾部的元素,以常量时间在任意端添加、删除元素。如果插入时没有空槽(slot)存在,那么自从上次重建(rebuild)至少线性数量插入必然已经发生,因此我们可以负担得起重建数组。如果移除一个元素,让比例n/m小于1/6,那么自从上次重建(rebuild)至少m/6= Ω ( n ) \Omega(n) Ω(n)个移除一定已经发生,因此我们也可以负担得起重建数组。

昂贵的线性时间重建之间,线性数量的操作确保每次动态操作花费最多 O ( 1 ) \mathcal{O}(1) O(1)时间。为了支持常量时间的数组索引,我们保存索引i:数组最左边的元素位置,以及数组存储元素数量n,对于每次更新以常量时间(最坏情形)来维持。为了访问存储在队列的 j t h j^{th} jth元素,确保 i+j<n,以常量时间(最坏情形)返回数组容器i+j处的元素。

1-4 Jen & Berry

课间休息时,Jen开着她的冰激淋小车到当地小学。所有孩子冲到她卡车前排队。Jen承载的学生数量(有2n个)溢出了,因此她叫了她的合伙人Berry,带来他的冰淇淋车帮她解脱。Berry很快到达,停在学生队伍的另一端。他为队伍最后的学生提供售卖,但其他学生反对:”最后的学生应该是最后面,这不公平“。

学生决定最公平的方式是纠正现状,把队伍的后半段(离Jen最远的n个孩子)反向排序,然后排到Berry的卡车,因此原始队伍的最后一名孩子,成为了Ben队伍中的最后一名孩子,原始队伍第 ( n + 1 ) s t (n+1)^{st} (n+1)st个孩子成为Berry的首个顾客。

(a)给定一个包含2n孩子姓名的链表,按照Jen的卡车前面形成的原始队列(首个节点包含队伍首个孩子的姓名),描述一个 O ( n ) \mathcal{O}(n) O(n)时间复杂度的算法,来更改链表,反转list后半段顺序。操作期间,你的算法应该不产生任何新的链表节点,或实例化任意新的非常量尺寸数据结构。

解:以3步反序list中后半段node节点:

*找到序列中 n t h n^{th} nth节点a(Jen队伍的最后)

*从 ( n + 1 ) s t (n+1)^{st} (n+1)st节点b到 ( 2 n ) t h (2n)^{th} (2n)th节点c遍历节点x,改变x的next指针,指向原始序列中x前的节点

*修改a的next指针指向c,b的next指针指向null

找 n t h n^{th} nth节点需要从list头部遍历next指针n-1次,可以通过简单循环以 O ( n ) \mathcal{O}(n) O(n)时间完成。我们可以通过减半list尺寸(保证是偶数)来计算n。

为了改变序列后半段的next指针,我们可以保存指向当前节点x、x前面节点 x p x_p xp​的指针,初始化b和a。然后记录x之后的节点为 x n x_n xn​,重新链接x指向 x p x_p xp​(x前面的节点,时间复杂度 O ( 1 ) \mathcal{O}(1) O(1)),我们可以改变当前节点为 x n x_n xn​,前驱节点为x,保存后驱需要的属性用于重新链接(relink)。重复n次,以 O ( n ) \mathcal{O}(n) O(n)时间重新链接(relink)序列后半段所有n节点。

最后,当算法遍历list时,通过记住节点a、b、c,意味着:改变头部异常的next指针,反向list后半段花费 O ( 1 ) \mathcal{O}(1) O(1),致使一个 O ( n ) \mathcal{O}(n) O(n)时间复杂度的算法。

(b)写一个python函数 reorder_students(L) 实现你的算法

解:

class Node:def __init__(self, name: str):self.name = nameself.next = Noneclass LinkedList:def __init__(self, head: Node):self.head = headdef get_list(num):head = Node(0)pre = headfor i in range(1, num):node = Node(i)        pre.next = nodepre = nodelist = LinkedList(head)list.size = numreturn listdef print_list(L):node = L.headfor _ in range(0, L.size):print(node.name)node = node.next        def reorder_students(L):n = L.size//2a = L.headfor _ in range(1, n):a = a.nextb = a.nextx_p,x = a,bfor _ in range(0, n):x_n = x.nextx.next = x_px_p, x = x, x_n        a.next = x_pb.next = Noneif __name__ == "__main__":list = get_list(10);print_list(list)print("---------------------------")reorder_students(list)print_list(list)

Mit6.006-problemSession01相关推荐

  1. [MIT6.006 算法导论] 1. Peak Finding 寻峰

    一.1D情况 假设有一个如下图的一维数组,格子下的数字代表它们的索引位置,格子内的字母代表该位置内的数值. 峰值的定义:当且仅当 b≥a 且 b≥c 时,位置2为峰值.(如果位置位于数组两个边界,则只 ...

  2. 计算机科学中的数学等(视频)

    [南开大学] 算法导论课程(参考书:算法设计) @张圣林老师 [南开大学] 算法导论课程(参考书:算法设计) @张圣林老师_哔哩哔哩_bilibili 算法导论课程[2020最新版] 算法导论课程[2 ...

  3. 基础006 宏基因组入门理论以及分析环境的部署

    本文"植物微生物组"公众号原创,ID: plantmicrobiome 作者:zhiwen 原文链接:基础006 宏基因组入门理论以及分析环境的部署 一.宏基因组核心思想 鉴定菌群 ...

  4. android 入门 006(sqlite增删改查)

    android 入门 006(sqlite增删改查) package cn.rfvip.feb_14_2_sqlite;import android.content.Context; import a ...

  5. ae万能弹性表达式_AE脚本精品表达式合集效果库 iExpressions 3.1.006【资源分享1453】...

    AE特效PR剪辑C4D影视后期 全世界只有不到1%的人关注了 你是个很特别的人 AE影视后期定期推送「AE+PR+C4D 影视特效合成 婚庆剪辑调色 电视广告包装 微电影制作 SpeedGrade达芬 ...

  6. 《iOS 8案例开发大全》——实例006 实现复杂的查找和替代工作

    本节书摘来自异步社区<iOS 8案例开发大全>一书中的实例006 实现复杂的查找和替代工作,作者 朱元波 , 陈小玉 , 胡汉平 , 张晨洁,更多章节内容可以访问云栖社区"异步社 ...

  7. 006 Android之Activity

    文章目录 四大组件之Activity Activety概述 Activity的响应事件 Activity之间的数据传递 数据传递实例 Activity的生命周期 Activity声明周期总结 Acti ...

  8. php统计凌晨6点,凌晨是哪一段时间,0:00-6:00(午夜到天亮前)

    过了午夜12点后,就是凌晨了,凌晨1点.凌晨2点--可到了6点,有人说是凌晨,有人说是早上,那凌晨是哪一段时间呢?对此,就由小编为大家解惑. 凌晨是哪一段时间 凌晨也叫黎明.破晓,它是指午夜到天亮前的 ...

  9. docker 容器 exited_Docker实战006:docker容器使用详解

    Docker容器也是docker的核心成员,是docker镜像的一个运行实例.一个镜像可以创建多个容器,多个容器也可以在同一台机器上运行并与其他容器共享操作系统内核同时将应用程序与系统其它周围环境隔离 ...

  10. 计算机三级数据库er图试题里,2019年3月计算机三级数据库考试基础试题及答案006...

    2019年3月计算机三级数据库考试基础试题及答案006 浏览次数:     时间:2019/03/29 1.设有关系模式R(A,B,C,D.,其函数依赖集为F={A->D,B->D,C-& ...

最新文章

  1. 防火墙 linux 端口,Linux配置防火墙端口 8080端口
  2. 为什么要叫python-为什么叫Python
  3. 60度斜坡怎么计算_【测绘】南方CASS土方计算方法—方格网法
  4. tomcat bug之部署应用的时候经常会发上startup failed due to previous errors
  5. Android实现支持缩放平移图片
  6. 物联网卡为什么会这么火,主要有哪些优势?
  7. 小程序飞入购物车特效
  8. PHP 7.3 比 PHP 7.0 快 22%,即将进入特性冻结阶段
  9. 为了自动驾驶,Uber每月烧钱1.3亿
  10. 在职场上被逼「造反」的文科生,半年后25k,还强硬的说我拿低了...
  11. java xml解析器_Java XML解析器
  12. 79. 基于 PHP 的用户认证
  13. 红蓝眼睛(答案在文章中找)
  14. Python 编写24点游戏
  15. 使用adb.exe禁止安卓手机app震动权限
  16. ABeam Insight | 女性科技系列(2):全球女性科技(FemTech)现状
  17. 温莎大学计算机硕士,温莎大学应用计算机硕士申请条件
  18. 洛谷 P4188 [USACO18JAN]Lifeguards (线段树)
  19. 三数之和给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组(GO,PHP)
  20. svg 绘制多边形渐变边框并填充渐变背景

热门文章

  1. 用matlab求解传递矩阵,用传递矩阵及MATLAB求解船舶轴系振动
  2. 某程序员哀叹:连帮三任女友进大厂,却惨遭分手
  3. 合同法律风险管理 合同管理中的刑事法律风险防范
  4. linux bogon,linux bogon
  5. GB/T 43497-2022 铝合金复合管材
  6. python编程超市购物系统_Python实现购物系统(示例讲解)
  7. 常用linux命令-less
  8. 揭秘日本5G智慧杆案例!附国外多杆合一、智慧路灯杆体设计造型方案
  9. 阿里easyExcel -- excel下载/导出/读取 (单元格自定义下拉选择、不支持图片)
  10. 你真的会用iPad吗,如何使iPad秒变生产力工具?在iPad上用vscode写代码搞开发