补学图论算法:算法竞赛入门经典(第二版)第十一章:

倒排索引还没有实现!

下面是左神的图论算法,并查集笔记.和一个美团题目.

'''
https://www.nowcoder.com/live/11?page=1
还是继续刷左程云的算法题.2.给定一个非负数的数组, 代表一个容器。 例如数组[0,1,0,2,1,0,1,3,2,1,2,1], 就是
以下图形中黑色的部分。如果用这个容器接水的话, 请问可以接多少水? 还以这个数组为例,
可以接 6 格水, 就是以下图形中蓝色的部分。3.给定一个非负数的数组, 数组中的每个值代表一个柱子的高度, 柱子的宽度是 1。 两个柱
子之间可以围成一个面积, 规定: 面积=两根柱子的最小值* 两根柱子之间的距离。 比如数
组[3,4,2,5]。 3 和 4 之间围成的面积为 0, 因为两个柱子是相邻的, 中间没有距离。 3 和
2 之间围成的面积为 2, 因为两个柱子的距离为 1, 且 2 是最短的柱子, 所以面积=1*2。3 和 5 之间围成的面积为 6, 因为两个柱子的距离为 2, 且 3 是最短的柱子, 所以面积=
3*2。 求在一个数组中, 哪两个柱子围成的面积最大, 并返回值。
#第三个题目显然就是单调栈的使用.
第二个题目一直没看懂.看懂了,就是第一节课课件里面的第三页的图片.
本质就是求数组的波谷即可.
第二个题目就是本质是求滑动窗口的最大值问题.比如位置i
那么就求比i小的位置的最大值,和比i大的位置的最大值.两个最大值最小的那个如果比i位置的数
大,那么我就返回这个差值就是i位置能存水的数量.
我去:滑动窗口的最大值问题.本质双端队列.
''''''
1.求两个子数组最大的累加和
【题目】
给定一个数组, 其中当然有很多的子数组, 在所有两个子数组的组合中, 找到相
加和最大的一组, 要求两个子数组无重合的部分。 最后返回累加和。
【要求】
时间复杂度达到 O(N)想到按每一个分店来分,然后分别算2个.那么算法是N^2的.
但是要N怎么算?
辅助数组么:
怎么个辅助数组法.
我开一个left数组:left[i]表示原来list[:i]上面的子数组最大累加和.
right[i]............................list[i:]...................
然后我i位置2个部分的最大累加和就是left[i]+right[i].
这样就O(N)了.
'''
def main(list1):def qiu_left(list1):out=-float('inf')sum=0p=[]for i in range(len(list1)):sum+=list1[i]if sum>out:out=sump.append(out)if sum<0:sum=0return pdef qiu_right(list1):return qiu_left(list1[::-1])a=qiu_left(list1)b=qiu_right(list1)out=-float('inf')for i in range(len(list1)-1):#注意这里的范围.tmp=a[i]+b[len(list1)-i-2]if tmp>out:out=tmpreturn out
print(main([32,432,65,675,-999,-65756]))'''
2.未排序正数数组中累加和为给定值的最长子数组长度
【题目】
给定一个数组 arr, 该数组无序, 但每个值均为正数, 再给定一个正数 k。 求 arr
的所有子数组中所有元素相加和为 k 的最长子数组长度。
例如, arr=[1,2,1,1,1], k=3。
累加和为 3 的最长子数组为[1,1,1], 所以结果返回 3。
【要求】
时间复杂度 O(N), 额外空间复杂度 O(1)
●类似背包问题,求出所有能拼成k的子数组的长度然后取max,但是复杂度很高.
貌似也不太高,用一个指针来表示读到那个位置即可.但是达不到O(N).
●感觉还是辅助数组.首先的到数组sum:sum[i]表示原来数组从0到i的求和.
把sum里面元素放哈希表里面key是sum[i] val 是i
然后给sum[i]找是否存在k+sum[i].整体效率N
●左神破题点:子数组问题:必须以那个位置作为结尾的情况下怎么怎么样...这是面试里面的套路.
'''
#经过左神的讲解.原来是双指针都在左面,然后开始移动,然后维护指针括住区域的sum即可.
def main(list1,k):left=0right=0sum=list1[0]p=-1while right<=len(list1)-1:if sum==k:tmp=right-left+1if tmp>p:p=tmpif sum>k:sum-=list1[left]left+=1if sum<=k and right<len(list1)-1: #便捷条件要扣sum+=list1[right+1]right+=1if right==len(list1)-1 and sum<=k: #便捷条件要扣breakreturn p
print(main([3,5,6,8,1,1,1,1,1,0.5,0.5,0.5,0.3],4))
'''
https://www.nowcoder.com/live/2/17/1
'''
'''
网盘内容:https://www.52pojie.cn/forum.php?mod=viewthread&tid=726182
'''
'''
学习第六课.图论算法.我学的最差的东西,也是结构性强,套路性强的题目,比赛很喜欢靠图论题目.
写过算法导论里面的,但是理解很差.也记不住.
'''
'''
美团2016笔试题目:
一个数组.求array[b]-array[a]最大值,并且b比a大.
N^2随便写,但是要N的效率呢?题目显然要一个切分点,那么每个切分之后效率是O(1).
这种效率一般都是预处理数组才能做到.所以需要做一个数组1[i]表示从0到i最小值.
一个数组2[i]表示从i到最后的最大值.然后两个一剪即可.
'''
def main(list1):mini=[]zuixiao=float('inf')for i in range(len(list1)):if list1[i]<zuixiao:zuixiao=list1[i]mini.append(zuixiao)list1=list1[::-1]maxi=[]zuida=-float('inf')for i in range(len(list1)):if list1[i]>zuixiao:zuida=list1[i]maxi.append(zuida)out=-float('inf')for i in range(len(list1)):tmp=maxi[i]-mini[len(list1)-2-i]if tmp>out:out=tmpreturn out
print(main([2,4,6,8,9,5,99999,-265]))#测试一下基本对了.强大的预处理数组技巧.美团的题目还是水平可以的.'''
并查集:
1.用于查如何A,B是否在一个集合中.
2.每一个集合设立一个头结点.其他都连向他
3.集合合并就是把小的集合挂到大的集合下面即可
4.优化.查询到一个a在b这个头结点下面,那么直接把a.next=b
'''
class bingcha():def __init__(self):self.fathermap={}self.sizemap={}def make_sets(self,list1):#把数据集list赋值到并查集里面做初始化for i in range(len(list1)):self.fathermap[list1[i]]=list1[i]self.sizemap[list1[i]]=1def find_father(self,node):#返回node的父节点是谁,然后把node挂到父节点上.father=nodeif self.fathermap[node]!=node:father=self.find_father(self.fathermap[node])self.fathermap[node]=fatherreturn fatherdef union(self,node1,node2):father1=self.find_father(node1)father2=self.find_father(node2)if father1!=father2:size1=self.sizemap[father1]size2=self.sizemap[father2]if size1>=size2:self.fathermap[node2]=father1self.sizemap[father1]+=size2else:self.fathermap[node1]=father2self.sizemap[father2]+=size1def in_same_set(self,node1,node2):return self.find_father(node1)==self.find_father(node2)
a=bingcha()
a.make_sets([1,2,3,4,5])
a.union(1,2)
a.union(1,3)
a.union(1,4)
print(a.in_same_set(2,4))
print(a.find_father(4))      #解决了并查集的代码实现.从直观上也能看出来,当已经查询或者插入了N次#再进行查询操作的画效率O(1).因为都已经连到根了.搜索1次即可.#继续理解并查集:他用树的加速来实现了并和查的操作,虽然他效率非常快,#但是不能进行交的操作.这就是他跟set的区别.set复杂度O(N).#并查集在图里面很实用.虽然面试对图考的不多,但是应该掌握.#下面就是左神给的图论问题模板,非常强大.能实现所有图论问题
#使用方法:对有向图就用graphgenerate,插入所有边即可.顺道就所有点都有了
#         对无向图,就插入2次,一次是from to 一次是to from即可.
'''
开始搞图:设计好几个类,然后存图,左神给的是邻接数组.
'''
class node():def __init__(self,val):self.val=valself.in1=0self.out=0self.nexts=[]self.edges=[]
class edge():def __init__(self,weight,from1,to):self.weight=weightself.from1=from1self.to=to#需要手动写上这几个比较函数.def __cmp__(self,other):return cmp(self.weight, other.weight)def __lt__(self,other):#operator < return self.weight < other.weightdef __ge__(self,other):#oprator >=return self.weight >= other.weightdef __gt__(self,other):#oprator >=return self.weight > other.weightdef __le__(self,other):#oprator <=return self.weight <= other.weightclass Graph():def __init__(self):self.nodes={}       #结构是key是题目给的编号,value是自己构造的node节点对象.#node.value也是编号.#因为要做复杂处理,所以第一步都是把对应编号转化成为node对象来进行处理.self.edges=set()
def GraphGenerator(matrix):#给矩阵,每一行都是 from,end,边长, 3个元素组成.graph=Graph()for i in range(len(matrix)):from1=matrix[i][0]to=matrix[i][1]weight=matrix[i][2]graph.nodes.setdefault(from1,node(from1))graph.nodes.setdefault(to,node(to))fromNode=graph.nodes[from1]toNode=graph.nodes[to]newEdge=edge(weight,fromNode,toNode)#这里面用node来做edge参数好么?fromNode.nexts.append(toNode)fromNode.out+=1toNode.in1+=1fromNode.edges.append(newEdge)graph.edges.add(newEdge)return graph'''
宽度优先遍历也叫广度优先遍历.
'''
'''
先写宽度便利:#利用一个队列和一个set
'''
import queue
def bfs(node):q=queue.Queue()q.put(node)visited=set([node])while q.empty()==False:tmp=q.get()print(tmp.val)#遍历的操作for i in tmp.nexts:if i not in visited:visited.add(i)q.put(i)
graph=GraphGenerator([[1,2,3],[2,4,5],[2,6,7],[4,6,5],[1,6,99],[99,98,999]])
print('ceshi')(bfs(graph.nodes[1])) #graph.nodes[1]表示1号节点对应的node'''
深度优先:只用一个set就行
'''##我自己写的菜鸟版本.函数每次都带visited.太慢了.左神用的是栈,来直接模拟递归过程.
#def dfs(node): #为了设立局部所以用函数嵌套来写,因为第一次运行时候,跟后面的代码要不同,
#              #多一行初始化visited,然后后面为了保持每个visited在每一次函数时候都一样,就传进去.
#    visited=set([node])
#    def mini_dfs(node,visited):#        print(node.val)#遍历的操作
#        for i in node.nexts:
#            if i not in visited:
#               mini_dfs(i,visited)
#               visited.add(i)
#    mini_dfs(node,visited)
#    return
#dfs(graph.nodes[1])def dfs(node):#大神的版本visited=set()fuzhu=[node]while fuzhu!=[]:node=fuzhu.pop()if node not in visited:print(node.val)visited.add(node) #node打印过了,就赶紧把他放visited里面.避免重复访问.for i in node.nexts:if i not in visited:#如果还有node的儿子i是没有访问过的,那么需要把node,i压回去.#就是用这个栈来替代递归过程.也就是递归改递推.fuzhu.append(node)fuzhu.append(i)break
print('ceshi2')
dfs(graph.nodes[1])
'''
拓扑排序:
找到全部入度为0的,全做完,然后删除这些节点相关的点和边,继续循环即可.
'''
def tuopu(graph):#任何一个有向无环图才可以拓扑排序a=queue.Queue()for i in graph.nodes.values():if i.in1==0:#入度是0.in是关键字没发使用,所以改成in1a.put(i)result=[]while a.empty()==False:tmp=a.get()result.append(tmp)for i in tmp.nexts:i.in1-=1if i.in1==0:a.put(i)return result
print('测试3')
for i in tuopu(graph):print(i.val)'''
最小生成树p算法.
''''''
最小生成树k算法. 这尼玛:直接贪心,每一次都选权重最小的边.不产生回路就加进来.
最后所有点都有了,就结束.你妈这么简单??????居然不会产生bug.顿时感觉最小生成树很low左神的最牛逼代码,用并查集来判断回路.有公共祖先就是有回路.
'''
from queue import PriorityQueue as PQueueimport heapq
def krustalMST(graph):#k算法实在是太短了.同样下面K算法也可以处理不连通的情况output=set()a=bingcha()a1=list(graph.nodes.values())a.make_sets(a1)#把所有nodes放并查集里面pq = PQueue()#给edge类加一个cmp方法即可.for i in graph.edges:pq.put(i)while pq.empty()!=True:tmp=pq.get()#如果tmp的from 和to 是在并查集里面有公共祖先的就不要了if a.in_same_set(tmp.from1,tmp.to)!=True:#表示不是环路#那么就加入这个变output.add(tmp)a.union(tmp.from1,tmp.to)return output#返回的是边的setprint('ceshi4')for i in krustalMST(graph):print(i.weight,i.from1.val,i.to.val)#效果可以.虽然是针对无向图,但是没有插入反向from1,to也效果#一样,因为我们考察的是边.'''
最小生成树:P算法.随便加进去一个点,然后找这个点的edge,加到pq里面,pq弹出一个最小的,加入tonode.循环
即可.
'''
def PrimMST(graph):output=set()result=set()pq=PQueue()for i in graph.nodes.values():#这个循环来处理整个图不联通的情况.if i not in output:output.add(i)for edge in i.edges:pq.put(edge)while pq.empty()!=True:tmp=pq.get()#道理都是每一次尽量走最短的边,if tmp.to not in output:result.add(tmp)#当弹出的边正好to节点没有访问,就是我们要的,放入result中!output.add(tmp.to)for pp in tmp.to.edges:pq.put(pp) #当新插入节点后,边的队列pq也更新一下即可.return result
print('ceshi5')
for i in PrimMST(graph):print(i.weight,i.from1.val,i.to.val)

View Code

补学图论算法:算法竞赛入门经典(第二版)第十一章:相关推荐

  1. UVA-12171 雕塑 题解答案代码 算法竞赛入门经典第二版

    GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版 这道题目在<算法竞赛入门经典第二版>书中标注了星号,也是第一道出现星号的 ...

  2. 算法竞赛入门经典第二版课后习题答案第二章

    算法竞赛入门经典第二版课后习题答案 第二章 习题2-1水仙花数 输出100-999中的所有水仙花数.若三位数ABC满足ABC=A^3+B^3+C^3,则称其为水仙花数.例如153=1^3+5^3+3^ ...

  3. 算法竞赛入门经典(第二版)-刘汝佳-第六章 数据结构基础 习题(12/14)

    文章目录 说明 习题 习6-1 UVA 673 平衡的括号 习6-2 UVA 712 S - 树 习6-3 UVA 536 二叉树重建 习6-4 UVA 439 骑士的移动 习6-5 UVA 1600 ...

  4. UVA-814 邮件传输代理的交互 题解答案代码 算法竞赛入门经典第二版

    GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版 AC代码 #include<iostream> #include< ...

  5. UVA-1598 交易所 题解答案代码 算法竞赛入门经典第二版

    GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版 AC代码 有意思的一个题目.书上说这是一个不错的优先队列练习题,但实际上它其实是一个 ...

  6. 算法竞赛入门经典(第二版) | 习题3-5 谜题 (UVa227,Puzzle)(World Finals 1993)

    乍一看是一个大水题,但World Finals这两个词标示着老子世界决赛真题虽然题目很水但是数据就能卡死你.整整搞了五个小时,期间经历过崩溃(花了这么多时间搞一道大水题,还没AC),但好在坚持下来了, ...

  7. 算法竞赛入门经典(第二版) | 例题4-3 救济金发放 (UVa133,The Dole Queue)

    提目(提交)链接→UVa-133 百度翻译→百度翻译 没使用过该网站的同学请猛戳这里→vJudge教程 分析: 最开始的固有思维是循环就用循环链表,其实完全可以把它看成一个大一点的周期类型题(一个大周 ...

  8. 算法竞赛入门经典(第二版) | 例题4-2 刽子手游戏 (UVa489,Hangman Judge)

    大家站在出题者的角度考虑,我们出了一道大水题,会让它又臭又长或是用复杂的函数吗? 不会.所以做这种题千万不要想得太复杂.循环+数组足矣. 提目(提交)链接→UVa-489 百度翻译→百度翻译 没使用过 ...

  9. 算法竞赛入门经典第二版:循环结构程序设计实例与习题

    实例: 1.阶乘之和 输入n,计算S= 1!+2!+3!+-+n!的末六位. 分析:两个循环,里面循环用于计算不同数的阶乘,外面一个循环用于将所有阶乘相加,核心算法 "for(int i=1 ...

最新文章

  1. IOS使用Instrument-Time Profiler工具分析和优化性能问题
  2. C++强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast
  3. MySQL中数据库的操作
  4. Caching Best Practices--reference
  5. js(三) ajax异步局部刷新技术底层代码实现
  6. 关于寻路算法的一些思考(6):预先计算好的路径的所用空间
  7. h5实现网页内容跟随窗口大小移动_h5页面能流行于各大社交平台必定有其原因的...
  8. ansible软件部署
  9. memcached命令行、Memcached数据导出和导入、php连接memcache、php的session存储到memcached...
  10. 内存颗粒和闪存颗粒的区别_NAND Flash闪存颗粒与SSD知识深度解析
  11. SQL Server 2008 R2数据库镜像部署
  12. tidb load data file 失败_TIDB运维之数据导入与导出
  13. 【手把手带你入门深度学习之150行代码的汉字识别系统】学习笔记 ·001 用OpenCV制作数据集
  14. 第三代计算机硬件特点是,第三代计算机的特征.doc
  15. 药易通显示rpc服务器不可用,药易通8825-8826日常问题语句归档教程方案.docx
  16. python tcl quartus_使用TCL脚本语言操作Quartus(一)
  17. JAVA-日期类(Date、SimpleDateFormat)
  18. Postman教程-Pre-request Script和Tests脚本进阶
  19. 《自适应机器人交互白皮书》
  20. GridView控件 Image控件 与图片的二进制数据库存储和显示

热门文章

  1. XMind生成PDF文档
  2. 移动安全框架:MDM 移动设备管理
  3. 大数据时代的新型数据库-图数据库Neo4j介绍
  4. Matplotlib,savefig保存图片不显示横纵坐标轴问题
  5. 一名计算机专业渣渣的2019春招求职经历—(成功收割华为、浦发、新华三、宝信软件offer)
  6. JAVA中的IO系统
  7. 此次为大家带来的是关于一些PLC编程控制入门常用到的实例,以此为借鉴,让学PLC的进度条缩短,加大掌握程度。里面包含的知识点是较为齐全的,如:I/O分配表、PLC接线图、梯形图程序等。 一、电动机顺
  8. 三星手机没有信号网络连接到服务器,手机没信号的原因以及解决方法
  9. 软件工程毕业设计课题(81)微信小程序毕业设计PHP校园跑腿小程序系统设计与实现
  10. pybullet GGCNN数据集制作(三)