python 的 list 效率底下? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
picy
V2EX    Python

python 的 list 效率底下?

  •  
  •   picy 2014-11-11 19:49:55 +08:00 8398 次点击
    这是一个创建于 4042 天前的主题,其中的信息可能已经有所发展或是发生改变。

    题目

    Design a stack that supports push, pop, top, and retrievingthe minimum element in constant time.

    • push(x) – Push element x onto stack.
    • pop() – Removes the element on top of the stack.
    • top() – Get the top element.
    • getMin() – Retrieve the minimum element in the stack.

    答案:

    class MinStack: def __init__(self): self.L=[] def pop(self): return self.L.pop() def push(self,x): self.L.append(x) def top(self): return self.L[-1] def getMin(self): tmpL = self.L[:] tmpL.sort() return tmpL[0] 

    每次提示答案都超时…表吐槽,表示刚学python

    43 条回复    2014-11-12 17:01:00 +08:00
    Altynai
        1
    Altynai  
       2014-11-11 20:13:04 +08:00   1
    你getMin复杂度都O(nlogn)了,题目说了**constant time**
    takato
        2
    takato  
       2014-11-11 20:41:20 +08:00 via iPhone   1
    常数级复杂度,只要额外维持一个最小值就可以了
    bcxx
        3
    bcxx  
       2014-11-11 21:07:48 +08:00
    @takato 不是一个,是最小值的历史记录
    wheatcc
        4
    wheatcc  
       2014-11-11 21:21:13 +08:00
    大力哥好!
    wzzyj8
        5
    wzzyj8  
       2014-11-11 22:58:35 +08:00
    getmin用list改用tuple,至少快10倍。


    bcxx
        6
    bcxx  
       2014-11-11 23:47:32 +08:00
    @wzzyj8 看题……不是 list 本身的问题- -
    staticor
        7
    staticor  
       2014-11-12 00:20:04 +08:00
    另外生成一个最小栈, push时比一下.
    ivanlw
        8
    ivanlw  
       2014-11-12 00:55:48 +08:00   1
    好经典的蒂姆
    rwalle
        9
    rwalle  
       2014-11-12 07:33:40 +08:00 via Android
    目测楼主以前没学过编程?经验太少 getMin这么简单的事情用sort就是杀鸡用牛刀
    ryd994
        10
    ryd994  
       2014-11-12 07:59:21 +08:00 via Android
    每次插入都和当前最小比较一下,小于就换
    每次pop就要重新sort了
    ryd994
        11
    ryd994  
       2014-11-12 07:59:46 +08:00 via Android
    pop可能要重新sort
    openroc
        12
    openroc  
       2014-11-12 08:27:18 +08:00
    gt11799
        13
    gt11799  
       2014-11-12 08:37:29 +08:00
    题主是只想实现一个可以取最小值的栈?
    heapq是一个最小堆,内部应该是一个二叉树,父节点始终小于子节点,因此顶点是最小的数。每当取出一个值,则两个子节点对比,小的上升。(实际上不是如此,不过这样容易理解)
    可以先使用heapq把这个类实现了,然后试试看,自己能不能写一个最小堆?
    msg7086
        14
    msg7086  
       2014-11-12 08:48:59 +08:00   1
    @gt11799
    我看题目里的要求,应该不是说要做小顶堆吧。应该是双stack,一个维护数据,另一个维护最小值。
    fkue0487
        15
    fkue0487  
       2014-11-12 08:52:05 +08:00
    不是有个min函数么.
    xcv58
        16
    xcv58  
       2014-11-12 08:57:30 +08:00 via Smartisan T1
    人家要 O(1) 你给弄个 O(n log n) Python 躺枪啊。
    rrfeng
        17
    rrfeng  
       2014-11-12 09:26:15 +08:00
    维护『一个』最小值的话 pop 了咋办?
    zhchbin
        18
    zhchbin  
       2014-11-12 09:28:59 +08:00
    ```python
    class MinStack:
    def __init__(self):
    self.data = []
    self.min_data = []

    def pop(self):
    if not self.data:
    return None

    self.min_data.pop()
    return self.data.pop()

    def push(self, x):
    self.data.append(x)
    if not self.min_data:
    self.min_data.append(x)
    else:
    self.min_data.append(min(self.min_data[-1], x))

    def top(self):
    return None if not self.data else self.data[-1]

    def getMin(self):
    return None if not self.data else self.min_data[-1]

    if __name__ == '__main__':
    min_stack = MinStack()
    data = [5, 2, 4, 3, -1, 0]
    for val in data:
    min_stack.push(val)
    print min_stack.getMin()

    min_stack.pop()
    print min_stack.getMin()
    min_stack.pop()
    print min_stack.getMin()
    ```

    经典的面试题目,刚学python,不知道写对了木有。
    zhchbin
        19
    zhchbin  
       2014-11-12 09:30:35 +08:00
    。。还以为支持Mardown直接回复了。。自行缩进吧。
    frankzeng
        20
    frankzeng  
       2014-11-12 09:35:24 +08:00
    return min(self.L)不就行了吗,干嘛自己实现?
    zhchbin
        21
    zhchbin  
       2014-11-12 09:42:49 +08:00
    @frankzeng min(self.L) 的复杂度应该是O(n)。
    ryanking8215
        22
    ryanking8215  
       2014-11-12 09:58:23 +08:00
    @zhchbin 好像不对吧,pop的时候,你怎么知道当前pop的那个值,在min_data里也需要pop掉,也即最大的那个?
    self.min_data.append(min(self.min_data[-1], x))
    这个明显不是O(1),怎么保证push是O(1)呢?
    scorpius
        23
    scorpius  
       2014-11-12 10:19:02 +08:00
    @openroc 感觉这个正解
    happywowwow
        24
    happywowwow  
       2014-11-12 10:38:16 +08:00
    o(1)的如何实现? 每次push的时候维护一个最小值?但请问pop的时候不是需要查询是否这个维护的值被pop了么?又需要重新找出最小的

    感觉得 双栈 或者 一栈一最小堆
    ipconfiger
        25
    ipconfiger  
       2014-11-12 10:44:03 +08:00
    leetcode 里用Python写的话一个栈就Memory溢出了,2个还不爆浆?
    picy
        26
    picy  
    OP
       2014-11-12 10:44:35 +08:00 via iPhone
    双栈的话会超出内存限制。无语了
    frankzeng
        27
    frankzeng  
       2014-11-12 11:49:04 +08:00
    @openroc https://gist.github.com/openroc/196642a254a542e4e80f.js 这一个请求是不是你弄的?这一串东西把整个贴拉到奇慢无比,这算不算是v2ex的bug呢?
    openroc
        28
    openroc  
       2014-11-12 12:46:25 +08:00
    gist被墙了。呵呵
    openroc
        29
    openroc  
       2014-11-12 12:48:09 +08:00
    @frankzeng 请科学上网。:)
    takato
        30
    takato  
       2014-11-12 12:49:40 +08:00
    @bcxx 感谢- -。笔误- -。。
    yakiang
        31
    yakiang  
       2014-11-12 13:09:34 +08:00
    我能说这是上个月珍爱网校招数据岗位的一道笔试题吗
    ChanneW
        32
    ChanneW  
       2014-11-12 13:20:03 +08:00
    我的第一想法是, 拖慢 pop push 速度,每次操作都更新最小值. 反而获取最小值只是把值返回.
    这样应该能过机器测试了,懒人的程序只做到刚好能用.
    caiych
        33
    caiych  
       2014-11-12 13:47:05 +08:00
    跟python和list都没什么关系……
    LZ需要学习一下基本的数据结构…这东西叫堆或者优先队列什么的…
    ---
    Python自带的优先队列居然没有top或者front这样的方法…只能拿出来看……
    bcxx
        34
    bcxx  
       2014-11-12 14:09:15 +08:00
    https://github.com/bcho/homework/blob/master/oj/leetcode/min_stack.py 的确是用两个 list 就可以过啊……


    @caiych 用优先队列也不是 O(1) 的…… 另外用 https://docs.python.org/2/library/heapq.html#heapq.nsmallest 这个就可以获取 top 和 front 了吧……
    zhchbin
        35
    zhchbin  
       2014-11-12 14:13:32 +08:00
    @ipconfiger @janstk 双栈可以过啊。。在上面的版本做空间上的优化。

    @ryanking8215 其实估计是排版的问题导致你没看清楚代码逻辑,懒得解释哈。
    hellove1985
        36
    hellove1985  
       2014-11-12 14:28:50 +08:00
    caiych
        37
    caiych  
       2014-11-12 14:36:00 +08:00
    @bcxx
    重新读了一遍题,发现想当然了。。。
    takato
        38
    takato  
       2014-11-12 15:30:28 +08:00
    @gt11799 堆的插入操作是O(logn)的
    takato
        39
    takato  
       2014-11-12 15:35:23 +08:00
    双栈可以的原因是因为栈不能pop任意位置,而只能pop顶,所以只需要发现目前值小于等于当前最小值的时候,push一个最小值的栈则可,否则就不push。
    pop的时候先检验最小堆栈顶是不是这个元素,是则pop,否则不变
    ryanking8215
        40
    ryanking8215  
       2014-11-12 15:46:11 +08:00
    @yakiang 这是leetcode上的题,主要是要求各操作都是O(1)的时间复杂度
    ryanking8215
        41
    ryanking8215  
       2014-11-12 16:00:56 +08:00
    @zhchbin 确实看错了,:)
    dingyaguang117
        42
    dingyaguang117  
       2014-11-12 16:52:41 +08:00
    pair的单栈,哈哈 就是比较浪费空间,有些最小值不必要存~
    push:
    -> push tuple(num, min)

    pop:
    -> pop tuple(num, min)
    picy
        43
    picy  
    OP
       2014-11-12 17:01:00 +08:00
    好吧终于过了,感谢上面回复的各位。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2628 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 12:49 PVG 20:49 LAX 04:49 JFK 07:49
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86