【问题标题】:Google Foobar : logical error in a sub optimal solutionGoogle Foobar:次优解决方案中的逻辑错误
【发布时间】:2020-03-01 16:09:59
【问题描述】:

问题

编写一个函数 answer(l),它接受一个正整数列表 l 并计算 (lst[i], lst[j], lst[k]) 的“幸运三元组”的数量,其中 i

幸运三元组基本上是元组 (x,y,z),其中 x 除 y,y 除 z。例如 (1,2,4)。

例如,[1, 2, 3, 4, 5, 6] 有三元组:[1, 2, 4], [1, 2, 6], [1, 3, 6],使得答案共 3 个。

我的代码

def isLuckyTriple(a,b,c):
    if b%a==0 and c%b==0:
        return True
    return False
def solution(l):
    count=0
    l=sorted(l)
    for i in range(len(l)-2):
        for j in range(i+1,len(l)-1):
            for k in range(j+1,len(l)):
                if isLuckyTriple(l[i],l[j],l[k]):
                    count+=1
    return count

我的问题

我已经查看了一些关于这个问题的 stackoverflow 答案。我知道如何以不同且更优化的方式来做到这一点。唯一的问题是我上面的代码在 5 个给定的测试用例中只通过了 2 个测试用例。我想了解我在以上代码中做错了什么。我更感兴趣的是找出我的错误,而不是以更好的方式去做。

如果您不认为代码不正确,那么是否会因为解决方案非常慢而导致测试用例失败?

我们将不胜感激。

【问题讨论】:

    标签: python algorithm logic


    【解决方案1】:

    删除 l=sorted(l) 步骤,因为它会更改数字索引的顺序,因为其中一个约束条件是 i < j < k

    考虑以下情况:

    4 2 1

    答案应该是0,但您的代码将返回1


    关于效率,你可以数出每个数从右开始除多少个数。对于1,2,3,4,5,6,每个的计数如下所示:

    1 2 3 4 5 6
    5 2 1 0 0 0 
    

    对于1,当您来到2 时,2 的缓存数组中已经有2,所以现在您有 2 个三元组要添加到最终答案中。当你来到3 时,你得到1 三元组,所以2+1 = 3

    时间复杂度: O(n^2)

    空间复杂度: O(n)


    既然问题是The elements of l are between 1 and 999999 inclusive,我认为您可以采用阶乘方式。

    首先收集地图中的所有值计数。

    现在,对每个数字进行每个倍数,然后从最后一个到第一个添加三连音。如下:

    triplet_map = {}
    map = {}
    for every number in array: # from last to first
       if number in triplet_map:
           triplets += triplet_map(number)
           continue
       cnt = 0
       for(i = number; i < 1000000; i *= number) 
         if i in map:
             if map(i) > 0: 
               cnt += map(i)
         map(number,map(number) + 1)
       triplets += cnt
       triplet_map(number,cnt)
    

    这样,就像每个数字的对数时间一样。没有测试这么多,但似乎工作。

    【讨论】:

    • 您好,感谢您的回复。我尝试使用 sorted(l) 验证我的解决方案,没有它,它仍然只通过 2 个测试用例。你能在上面的代码中看到任何其他错误吗?是的,你做的最后一个代码要好得多。
    • @MuhammadAnasBhatti 如果没有sorted(l),它应该可以工作。您可以尝试建议的 O(n^2) 解决方案。也许 FooBar 不会报告时间限制超出问题,而只是报告通过或失败。
    • 我认为你是对的。必须限制执行时间。除了您的解决方案之外,我还想到了另一种解决方案,在该解决方案中,我从左侧找到每个元素的分隔符,从右侧找到每个元素的倍数,然后将两者的计数相乘。这为我提供了单个元素的可能元组数量。我将它添加到我的 TotalCount 变量中。你认为它会起作用吗?
    • @VeryBhatti 这也应该可以。因为我们正在寻找索引 i,j,k,所以只需从左右计算重复项。
    【解决方案2】:
    def answer(l):
        triples_count=0
    
        p=len(l)
        print l
        for i in xrange(p-2):
            for j in xrange(i+1, p-1):
                if l[j] % l[i] == 0:
                    for k in xrange(j+1, p):
                        if l[k] % l[j] == 0:
                            #print l[i], l[j], l[k]
                            triples_count=triples_count+1
        return(triples_count)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-04
      • 1970-01-01
      • 2013-10-28
      • 1970-01-01
      • 1970-01-01
      • 2020-11-25
      • 1970-01-01
      相关资源
      最近更新 更多