zoukankan      html  css  js  c++  java
  • Deques and Randomized Queues

    1. 题目重述

    完成三个程序,分别是双向队列,随机队列,和随机队列读取文本并输出k个数。

    2. 分析

    2.1 双向队列

    题目的性能要求是,操作时间O(1),内存占用最大48n+192byte。

    当使用单向链表时,尾端删除需要从链表头遍历,才能知道新的链表头,操作时间无法满足。

    当使用变长数组时,当头尾均为1/4时,内存使用为~56N,不满足情况。

    选用双向链表实现。

    2.2 随机队列

    题目性能要求时,操作时间O(1), 内存占用最大48n+192byte。

    由于是随机操作,所以链表不适用,链表只能遍历,不能随机访问,操作时间无法满足。

    使用变长数组,数组可以随机访问,占用内存为~8N到~32N,满足题目要求。

    但是但是,数组不能从中间删除内容,这个地方卡了我很久,最后看了书上的提示才想到。这里存在了思维定式,考虑题目要求,这个随机队列不存在对内容顺序的需求,所以不需要维护队列的顺序。数组虽然不能从中间删除,但是可以删除末尾元素,这就意味着,只需要将末尾数据拷贝到当前位置,并缩短实际元素的长度,也就删除了此元素。

    2.3 队列读取并输出

    这里就是建立一个随机队列,然后enqueue,再dequeue k个就好了。这个思路无法完成extra的要求,关于extra如何实现见下文。

    3. 实现

    具体实现见代码DequeRandomizedQueuePermutation

    下面分析自己在实现中的bug。

    3.1 双向队列

    1. 第一遍实现在插入和删除时没有更新size。只会照葫芦画葫芦,教程里没讲的就不会写
    2. 在只有一个元素时,删除头部指针没有更新尾部指针,删除尾部也没更新头部。造成访问溢出。

    3.2 随机队列

    1. 首先,思维定式,看了queue的变长数组实现,总觉得随机队列需要记录真实数据的头、尾位置。然而实际上随机队列删除元素的方式和队列不同,即使从头部删除文件,也不会使数组在前侧有未使用的元素。
    2. dequeue时没有考虑内存缩减。在内存缩减是,最开始比较的是N和size的大小,这俩就是一个啊!!实际应该比较的是申请的数组的大小和N的大小。
    3. 删除元素时,应该将S[N - 1]的内存拷贝到被删除的位置,不是S[N]!数组是从0开始的啊!退群吧

    至此,已经可以拿到100分了。可喜可贺可喜可贺。

    4. extra

    extra是针对随机队列读取并输出k个数的,这里要求随即队列的对象数目仅仅为k。按照之前思路2.3的分析,若输入队列拥有n个对象,则随机队列中对象数目为n,不满足要求。

    具体使用的方法是使用水塘抽样

    我在查了资料之后将理应有的分析写一下,期望自己以后能有这么清晰的思路。

    1. 最后从队列中输出k个数,也就意味着每个数被输出的概率为$k/n$。
    2. 那么将每个读取的数目按照$k/n$的概率加入到队列中,(自己能做到这一步就够了,这次是脑子里什么都没有)。
    3. 但是这里n不知道。之后就是数学方法了,这个我只能看懂,确实不知道怎么推的。概率学的不好

  • 相关阅读:
    继续聊WPF
    窥探Swift之别具一格的Struct和Class
    窥探Swift之类的继承与类的访问权限
    iOS开发之地图与定位
    iOS开发之WebView
    iOS开发之版本控制(SVN)
    iOS开发之抽屉效果实现
    iOS开发之调用系统打电话发短信接口以及程序内发短信
    转:GitHub 万星推荐成长技术清单
    vmware漏洞之四:简评USE-AFTER-SILENCE: EXPLOITING A QUIETLY PATCHED UAF IN VMWARE
  • 原文地址:https://www.cnblogs.com/huipengly/p/9626008.html
Copyright © 2011-2022 走看看