Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 降到零问题-获取时间超过错误_Python_Algorithm_Optimization_Breadth First Search_Factors - Fatal编程技术网

Python 降到零问题-获取时间超过错误

Python 降到零问题-获取时间超过错误,python,algorithm,optimization,breadth-first-search,factors,Python,Algorithm,Optimization,Breadth First Search,Factors,试图解决hackerrank 您将得到Q查询。每个查询由单个数字N组成。在每个移动中,您可以对N执行2个操作。如果N=a×b(a≠1,b≠1) ,我们可以更改N=max(a,b)或将N的值减小1。 确定将N值减为0所需的最小移动次数 我使用BFS方法来解决这个问题 a。使用seive生成所有素数 b。使用素数,我可以简单地避免计算因子 c。我把-1和所有的因子排成一列,以得到零 d。我还使用了以前的结果来避免将遇到的数据排队 这仍然给了我时间。有什么想法吗?代码中还添加了注释 import ma

试图解决hackerrank

您将得到Q查询。每个查询由单个数字N组成。在每个移动中,您可以对N执行2个操作。如果N=a×b(a≠1,b≠1) ,我们可以更改N=max(a,b)或将N的值减小1。 确定将N值减为0所需的最小移动次数

我使用BFS方法来解决这个问题

a。使用seive生成所有素数

b。使用素数,我可以简单地避免计算因子

c。我把-1和所有的因子排成一列,以得到零

d。我还使用了以前的结果来避免将遇到的数据排队

这仍然给了我时间。有什么想法吗?代码中还添加了注释

import math
#find out all the prime numbers
primes = [1]*(1000000+1)
primes[0] = 0
primes[1] = 0
for i in range(2, 1000000+1):
  if primes[i] == 1:
    j = 2
    while i*j < 1000000:
      primes[i*j] = 0
      j += 1

n = int(input())
for i in range(n):
  memoize= [-1 for i in range(1000000)]
  count = 0
  n = int(input())
  queue = []
  queue.append((n, count))
  while len(queue):
    data, count = queue.pop(0)
    if data <= 1:
      count += 1
      break   
    #if it is a prime number then just enqueue -1
    if primes[data] == 1 and memoize[data-1] == -1:
      queue.append((data-1, count+1))
      memoize[data-1] = 1
      continue
    #enqueue -1 along with all the factors
    queue.append((data-1, count+1))
    sqr = int(math.sqrt(data))
    for i in range(sqr, 1, -1):
      if data%i == 0:
        div = max(int(data/i), i)
        if memoize[div] == -1:
          memoize[div] = 1
          queue.append((div, count+1))
  print(count)
导入数学
#找出所有的素数
素数=[1]*(1000000+1)
素数[0]=0
素数[1]=0
对于范围(210000+1)内的i:
如果素数[i]==1:
j=2
当i*j<1000000时:
素数[i*j]=0
j+=1
n=int(输入())
对于范围(n)中的i:
memoize=[-1表示范围内的i(1000000)]
计数=0
n=int(输入())
队列=[]
queue.append((n,count))
而len(队列):
数据,计数=queue.pop(0)

如果数据,则有两大原因导致此代码的速度缓慢

清除数组比清除集合慢 第一个问题是这一行:

memoize= [-1 for i in range(1000000)]
if primes[data] == 1 and memoize[data-1] == -1:
这将准备100万个整数,并针对1000个测试用例中的每一个执行。一种更快的方法是简单地使用Python集来指示哪些值已经被访问过

正在执行不必要的循环 第二个问题是这一行:

memoize= [-1 for i in range(1000000)]
if primes[data] == 1 and memoize[data-1] == -1:
如果你有一个素数,并且你已经访问了这个数,你实际上是在做一个缓慢的循环,搜索素数因子,而这个素数因子永远不会找到任何解(因为它是素数)

更快的代码 事实上,使用集合带来的改进是如此之大,以至于您甚至不需要基本测试代码,并且以下代码在时间限制内通过了所有测试:

import math
n = int(input())
for i in range(n):
  memoize = set()
  count = 0
  n = int(input())
  queue = []
  queue.append((n, count))
  while len(queue):
    data, count = queue.pop(0)
    if data <= 1:
      if data==1:
        count += 1
      break   
    if data-1 not in memoize:
        memoize.add(data-1)
        queue.append((data-1, count+1))
    sqr = int(math.sqrt(data))
    for i in range(sqr, 1, -1):
      if data%i == 0:
        div = max(int(data/i), i)
        if div not in memoize:
          memoize.add(div)
          queue.append((div, count+1))
  print(count)
导入数学
n=int(输入())
对于范围(n)中的i:
memoize=set()
计数=0
n=int(输入())
队列=[]
queue.append((n,count))
而len(队列):
数据,计数=queue.pop(0)

如果数据或者,有一个
O(n*sqrt(n))
时间和
O(n)
空间复杂度解决方案可以通过所有测试用例

其思想是缓存每个非负整数的最小计数,最多为
1000000
(问题中可能的最大输入数)之前运行任何查询。这样做之后,对于每个查询,只需返回缓存中存储的给定数字的最小计数。因此,每个查询检索结果的时间复杂度将是
O(1)

为查找每个数的最小计数(我们称之为代码< Lex2ZoCouts ),我们应考虑以下几个情况:

  • 0
    1
    具有相应的
    0
    1
    最小计数
  • 素数
    p
    除了
    1
    和自身之外没有其他因子。因此,它的最小计数是
    1
    加上
    p-1
    的最小计数,或者更正式地说
    down2zeroccounts[p]=down2zeroccounts[p-1]+1
  • 对于复合数字
    num
    来说,它有点复杂。对于任何一对系数
    a>1,b>1
    ,使得
    num=a*b
    num
  • 的最小计数为
    down2zeroccounts[a]+1
    down2zeroccounts[b]+1
    down2zeroccounts[num-1]+1
    因此,我们可以逐步为每个数字按升序建立最小计数。计算每个后续数字的最小计数将基于较低数字的最佳计数,因此最终将建立最佳计数列表

    为了更好地理解该方法,请检查代码:

    from __future__ import print_function
    
    import os
    import sys
    
    maxNumber = 1000000
    down2ZeroCounts = [None] * 1000001
    
    def cacheDown2ZeroCounts():
        down2ZeroCounts[0] = 0
        down2ZeroCounts[1] = 1
    
        currentNum = 2
        while currentNum <= maxNumber:
            if down2ZeroCounts[currentNum] is None:
                down2ZeroCounts[currentNum] = down2ZeroCounts[currentNum - 1] + 1
            else:
                down2ZeroCounts[currentNum] = min(down2ZeroCounts[currentNum - 1] + 1, down2ZeroCounts[currentNum])
    
            for i in xrange(2, currentNum + 1):
                product = i * currentNum
                if product > maxNumber:
                    break
                elif down2ZeroCounts[product] is not None:
                    down2ZeroCounts[product] = min(down2ZeroCounts[product], down2ZeroCounts[currentNum] + 1)
                else:
                    down2ZeroCounts[product] = down2ZeroCounts[currentNum] + 1    
    
            currentNum += 1
    
    def downToZero(n):
        return down2ZeroCounts[n]
    
    if __name__ == '__main__':
        fptr = open(os.environ['OUTPUT_PATH'], 'w')
    
        q = int(raw_input())
    
        cacheDown2ZeroCounts()
        for q_itr in xrange(q):
            n = int(raw_input())
    
            result = downToZero(n)
    
            fptr.write(str(result) + '\n')
    
        fptr.close()
    
    from\uuuuu future\uuuuu导入打印功能
    导入操作系统
    导入系统
    maxNumber=1000000
    down2ZeroCounts=[None]*1000001
    def CachedDown2ZeroCounts():
    down2zeroccounts[0]=0
    down2zeroccounts[1]=1
    currentNum=2
    而currentNum maxNumber:
    打破
    elif down2ZeroCounts[产品]不是无:
    down2zeroccounts[product]=min(down2zeroccounts[product],down2zeroccounts[currentNum]+1)
    其他:
    down2ZeroCounts[产品]=down2ZeroCounts[当前数量]+1
    currentNum+=1
    def降到零(n):
    返回down2zeroccounts[n]
    如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
    fptr=open(os.environ['OUTPUT_PATH'],'w')
    q=int(原始输入()
    cacheDown2ZeroCounts()
    对于X范围内的q_itr(q):
    n=int(原始输入()
    结果=降到零(n)
    fptr.write(str(结果)+'\n')
    fptr.close()
    
    但是如果素数[data]==1将检查素数,如果是素数,我将对素数-1进行搜索,但没有找到任何因素。检查continue语句。此解决方案也给出了TLE。我同意当memoize[data-1]==1时,但是如果primes[data]==1和memoize[data-1]==1,您认为会发生什么?在这种情况下,我相信continue语句不会被执行。在TLE方面,请确保您使用的是Python 2.7或pypy目标之一。(这些比普通Python快3)这很奇怪,它对我来说很好。我所能建议的就是仔细检查代码是否与这里所写的完全一致——请注意,当您更改语言时,网站会为您重新加载以前的解决方案。