python 的 list 效率底下?

2014-11-11 19:49:55 +08:00
 janstk

题目

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

答案:

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

8296 次点击
所在节点    Python
43 条回复
zhchbin
2014-11-12 09:42:49 +08:00
@frankzeng min(self.L) 的复杂度应该是O(n)。
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
2014-11-12 10:19:02 +08:00
@openroc 感觉这个正解
happywowwow
2014-11-12 10:38:16 +08:00
o(1)的如何实现? 每次push的时候维护一个最小值?但请问pop的时候不是需要查询是否这个维护的值被pop了么?又需要重新找出最小的

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

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

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/145709

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX