【问题标题】:Memory limit exceeded in PythonPython中超出内存限制
【发布时间】:2019-11-07 06:26:53
【问题描述】:

我正在解决一个需要整数列表或大小为 10^18 的字典的问题。运行代码时,编译器会抛出一条错误消息“超出内存限制”。

这是我的代码:

def fun(l, r, p):
    #f = [None, 1, 1]
    f = {0:0, 1:1, 2:1}
    su = 0
    for i in range(1, r):
        if i%2 == 0:
            f[i+2] = 2*f[i+1] - f[i] + 2
            #f.append(2*f[i+1] - f[i] + 2)
        else:
            f[i+2] = 3*f[i]
            #f.append(3*f[i])

    for k in range(l, r):
        su = su + f[k]

    su = (su + f[r]) % p
    print(su)

t, p = input().split()
p = int(p)
t = int(t)
#t = 3
#p = 100000007
for i in range(t):
    l , r = input().split()
    l = int(l)
    r = int(r)
    fun(l, r, p)

它显示超出内存限制,最大内存使用量为 306612 KiB。

【问题讨论】:

  • 您真的有一台内存为 1 EB 的计算机吗?因为如果你有那个,你一定是来自遥远未来的时间旅行者,我想借你的时间机器。
  • 您必须设计一种在有限内存空间中运行的算法。你不能指望获得无限量的内存......至少在这个时候...... 10^18?

标签: python memory python-3.5


【解决方案1】:

这里有两个观察:

  • 您不需要同时存储所有数字。您可以使用 deque 和 generator 函数通过仅跟踪生成的最后三位而不是整个序列来生成数字。

      import itertools
      from collections import deque
    
      def infinite_fun_generator():
          seed = [0, 1, 1]
          dq = deque(maxlen=2)
          dq.extend(seed)
          yield from seed
          for i in itertools.count(1):
              if i % 2 == 0:
                  dq.append(2 * dq[-1] - dq[-2] + 2)
              else:
                  dq.append(3 * dq[-2])
              yield dq[-1]
    
      def fun(l, r, p):
          funs = itertools.islice(infinite_fun_generator(), l, r + 1)
          summed_funs = itertools.accumulate(funs, lambda a, b: (a + b) % p)
          return deque(summed_funs, maxlen=1)[-1]
    
  • 您可能有更好的机会在 Math.SE 中提出这个问题,因为我现在不想进行数学运算,但就像 Fibonacci sequence 一样,您可能有一个解析解决方案可用于计算第 n 个成员无需迭代地计算中间数,甚至可以解析地推导出一个公式来计算常数时间内的总和。

【讨论】:

  • 这可以完美消除内存错误,但无法消除 Time Limit Exceeded 错误,因为 10^18 范围内的每个测试用例都需要将近 5 秒才能执行,这不是一个好的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-24
  • 2019-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多