为什么该脚本的运行时为O(n ^ 2)?

时间:2019-02-05 12:46:06

标签: python algorithm big-o

我正在接受McDowell撰写的“ Cracking the Coding Interview”,我对一种算法有疑问(这是第六版第69页的最后一个程序)。我在下面使用Python编写了它。对于a,b,c,d为1到1000的整数,应该找到a ^ 2 + b ^ 2 = c ^ 2 + d ^ 2的时间。显然,它在O(n ^ 2)时间内运行。我知道双循环为O(n ^ 2),但我看不到如何分析随后的三重循环。显然它是O(n ^ 2)或更小,但我不知道为什么。

# This algorithm solves the above problem by making a 
# key for every unique a^2+b^2 sum... then the value for each key is
# a list of a,b tuples that I append to every time there is another a,b 
# with a given a^2+b^2 sum.
# Note that since a,b,c,d each on their own can take on any value 
# from 1 to 1000, we don't ever have to create the c^2+d^2 values
# since they will be the same as the a^2+b^2 values (the triple loop
# takes care of that idea).

sum_pair_dict = {}

n = 1001
for a in range(1,n):
    for b in range(1, n):
        sum = a**2 + b**2
        if sum in sum_pair_dict:
            sum_pair_dict[sum].append((a,b))
        else:
            sum_pair_dict[sum] = [(a,b)]

for a_sum, pair_list in sum_pair_dict.items():
    for pair1 in pair_list:
        for pair2 in pair_list:
            print(pair1, pair2)

2 个答案:

答案 0 :(得分:1)

  • 实际算法包含在仅前两个for循环中。这样就可以进行实际处理(求解方程式)

  • 确实,第二个 3个嵌套循环在O(n ^ 3)中运行,它们仅用于打印结果,并且实际上没有进行任何处理

答案 1 :(得分:0)

这实际上是一个非常合理的问题,但是需要一些上下文来了解原因。 McDowell提供的前四个解决方案都是print解决方案,是求解方程式的一部分。例如,先前的四个解决方案之一是:

def solve_brute_force(n):
    for a in range(1, n):
        for b in range(1, n):
            for c in range(1, n):
                for d in range(1, n):
                    if a**3 + b**3 == c**3 + d**3:
                        print(a, b, c, d)

McDowell的最终解决方案实际上无法与之前的四个解决方案相比,因为它将打印解决方案与求解方程式分开。所以那不是很好。但我变得更糟:

如果print的代码被删除,而我们仅运行实际算法(如@molamk所说):

def solve(n):
    sum_pair_dict = {}

    for a in range(1,n):
        for b in range(1, n):
            sum = a**2 + b**2
            if sum in sum_pair_dict:
                sum_pair_dict[sum].append((a,b))
            else:
                sum_pair_dict[sum] = [(a,b)]

    # just dump the results
    print(sum_pair_dict)

假设我们求解n = 4,我们得到:

{
  2: [(1, 1)],
  9: [(1, 2), (2, 1)],
  28: [(1, 3), (3, 1)],
  16: [(2, 2)],
  35: [(2, 3), (3, 2)],
  54: [(3, 3)]
}

这是(IMO)和中间格式,可用于得出解决方案。例如,有效的解决方案是a=1b=1c=1d=1。结果(sum_pair_dict1中未显示。 a=2b=2c=2d=2a=3b=3c=3d=3都不

实际上,不仅缺少a=b=c=d的结果,而且还有很多结果。要获得这些结果,需要以下循环

for a_sum, pair_list in sum_pair_dict.items():
    for pair1 in pair_list:
        for pair2 in pair_list:
            print(pair1, pair2)

好多了,现在我们看到了缺少的结果:

(1, 1) (1, 1) <------
(1, 2) (1, 2)
(1, 2) (2, 1) <------
(2, 1) (1, 2) <------
(2, 1) (2, 1) <------
(1, 3) (1, 3) <------
(1, 3) (3, 1)
(3, 1) (1, 3) <------
(3, 1) (3, 1) <------
(2, 2) (2, 2) <------
(2, 3) (2, 3) <------
(2, 3) (3, 2)
(3, 2) (2, 3) <------
(3, 2) (3, 2) <------
(3, 3) (3, 3) <------

@okcapp,我认为这值得更正,可以在https://careercup.wufoo.com/forms/cracking-the-book-bug-report/提交