算法:高效的队列deque

一、题目:

有一个序列u,满足:

1. 第一个元素是1

2. 此后任意一个元素x,2x+1和3x+1也必定在u中

现给定整数n,求序列u中的第n个元素是什么?并输出该序列

规定:要注意算法的效率

二、分析

先找几个数计算一下:

1

[1], 3, 4

1, [3], 4, 7, 10

1, 3, [4], 7, 9, 10, 13

其中这个9提醒我们,虽然单纯的2x+1或3x+1一定是递增的,但是前一个数的3x+1有可能大于后一个数的2x+1。因此,当要在序列u中取“下一个数”计算它的2x+1和3x+1时,如何选取?

笨办法是用一个列表保存序列u,每计算出一个新的2x+1和3x+1时,都遍历一遍当前的列表,然后找到适当的位置插入。这显然不符合本题对于效率的要求。

换一个角度思考:如果我们不是用一个列表,而是用两个列表表示序列u呢?这两个列表分别保存2x+1和3x+1的值。由于它们一定是递增的,新元素只要直接append在队尾即可。而“选取下一个数”的动作,相当于从两个列表的队首依次挑出较小的那一个。这道题目进一步变形为:两个已经各自按从小到大顺序排列的列表,如何合并为一个从小到大排序的列表?

三、实现要点

1. 高效的队列:

用deque。这篇文章比较了deque, queue, 和list的性能。

2. 两个已经各自按从小到大顺序排列的列表,如何合并为一个从小到大排序的列表?

取两个队首的最小值,并pop该最小值元素。下一次循环仍然取两个队首的最小值。

四、过程分析

五、实现代码

 1 #-*- coding:utf-8 -*-
 2 __author__ = ‘Administrator‘
 3
 4 from collections import deque
 5
 6 #返回列表中第n+1个元素
 7 def deq_linear(Len):
 8     count_n=1;h=1;d1=deque([]);d2=deque([])
 9     d_total=deque([1])
10     while True:
11         if count_n>=Len:
12             return h,d_total
13         d1.append(2*h+1)
14         d2.append(3*h+1)
15         Min=min(d1[0],d2[0])
16         if d1[0]==Min:
17             h=d1.popleft()
18             d_total.append(h)
19         else:
20             h=d2.popleft()
21             d_total.append(h)
22         count_n=count_n+1
23
24 if __name__=="__main__":
25     Len=10
26     h,li=deq_linear(Len)
27     print("长度为 %d 的序列:%s" %(Len,list(li)))
28     print("该序列第 %d 个元素为:%d" %(Len,h))
29     #输出:
30     #长度为 10 的序列:[1, 3, 4, 7, 9, 10, 13, 15, 19, 21]
31     #该序列第 10 个元素为:21

时间: 2024-10-09 23:40:47

算法:高效的队列deque的相关文章

nyoj1117 鸡蛋队列 (双端队列,deque)

题目1117 题目信息 运行结果 本题排行 讨论区 鸡蛋队列 时间限制:1000 ms  |  内存限制:65535 KB 难度:1 描述 将两根筷子平行的放在一起,就构成了一个队列.将带有编号的鸡蛋放到两根筷子之间叫做入队(push),将筷子之间的鸡蛋拿出来叫做出队(pop).但这两种方式有特殊的定义,对于入队,只能将鸡蛋从队列的尾部向里放入:对于出队,只能将鸡蛋从队列的头部向外将鸡蛋拿出来. 将①.②入队: 头____________尾                         ___

经典白话算法之优先级队列

<1>概念 优先级队列,顾名思义,就是一种根据一定优先级存储和取出数据的队列.它可以说是队列和排序的完美结合体,不仅可以存储数据,还可以将这些数据按照我们设定的规则进行排序.优先级队列是堆的一种常见应用.有最大优先级队列(最大堆)和最小优先级队列(最小堆).优先级队列是一种维护有一组元素构成的集合S的数据结构. <2>优先队列支持的基本运算 [cpp] view plaincopy //建立一个保存元素为int的优先级队列,其实是建了一个小顶堆 //但是请特别注意这样的建的堆默认是

数据结构与算法--栈、队列(队列)

Hello,everybody.我们又见面了.今天我们来学习一下队列这个数据结构,let's Go,开始我们的征程吧. 首先,举两个生活中的常见例子.相信大家,在用电脑工作娱乐时,都会碰到这样的现象.当我们点击程序或进行其他操作时,电脑处于死机状态.正当我们准备Reset时,它突然像打了鸡血似的,突然把刚才我们的操作,按顺序执行了一遍.之所以会出现这个现象,是因为操作系统的多个程序,需要通过一个管道输出,而按先后顺序排队造成的. 还有有个例子,在我们打客服热线时,有时会出现等待的现象.当其他客户

双端队列deque的应用

collections模块作为基础数据类型的一种扩展,提供了更为丰富的数据结构支持.和list相比,双端队列deque在数组的首部和尾部进行增加和删除元素的时间复杂度都为O(1).而list在数组尾部进行操作的时间复杂度为O(1),在首部进行增加删除数据的时间复杂度为O(n)(涉及到整个数组元素的移动). Deques支持线程安全,内存有效的在队列两端进行删除增加元素操作,在任一方向上具有大致相同的O(1)性能. 类原型:collections.deque([iterable[, maxlen]

励志成为优产的母猪--------猜数游戏 ,历史记录,pickle保存,队列deque

# pickle 可以处理复杂的序列化语法.(例如自定义的类的方法,游戏的存档等),存档以文件的形式保存 参见 https://www.cnblogs.com/abobo/p/8080447.html # collections是Python内建的一个集合模块,提供了许多有用的集合类.参见 https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001411031239400f7181

C语言算法系列---1.队列和栈

写在前面:在家玩了好久,实在是不知道干嘛了,突然想找些事做,现在是时候做些什么了.这些东西不见得多高深,也可能很简单,但很基础,也无法忽视.同时,也是自己学习走过的一条路. 这是开头,就写写C的队列和栈的一些算法吧. 首先是栈的一些基础功能的实现,先贴代码: #include<stdlib.h> #include<stdio.h> typedef int SElemType; //声明栈元素类型为int typedef int Status; //函数返回值的类型为int #def

初学图论-Dijkstra单源最短路径算法基于优先级队列(Priority Queue)的实现

这一次,笔者使用了STL库中的优先级队列(Priority Queue)来完成Dijkstra算法中extract-min()语句(即从未选中的节点中选取一个距离原点s最小的点)的功能.由于优先级队列的插入.删除操作只需要logn的时间花费,因此降低了不少运行时间. 本文使用C++实现了这一基本算法.参考<算法导论>第24.3节. /**  * Dijkstra's Single Source Shortest Path Algorithm in C++  * Time Cost : O(Ml

算法 - 栈与队列(C 语言实现)

目标: 理解 栈 与 队列 这两种数据结构, 并且知道如何应用. 算法 + 数据结构 = 程序 一.堆栈 堆栈是一组元素的集合,类似于数组,但数组可以按下标访问,堆栈的访问规则只能为push 与 pop 两种操作. 堆栈只能访问或者移出栈顶的元素.

C++ STL 双端队列deque详解

一.解释 Deque(双端队列)是一种具有队列和栈的性质的数据结构.双端队列的元素可以从两端弹出,其限定插入和删除操作在表的两端进行. 二.常用操作: 1.头文件 #include <deque> 2.定义 a) deque<int>s1; b) deque<string>s2; c) deque<node>s3; /*node为结构体,可自行定义.*/ 3.常用操作 //a) 构造函数 deque<int> ideq //b)增加函数 ideq