我是否需要学习总结,如果是,那么任何书籍都可以参考?
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j+=i)
printf("*");
答案 0 :(得分:4)
这个问题可以通过检查来解决:
n = 16
i | j values | # terms
1 | 1, 2, ..., 16 | n
2 | 1, 3, 5, ..., 16 | n / 2
.. | .. | n / 3
16 | 16 | n / n
在上表中,i
是外循环值,j values
显示内循环的迭代。通过检查,我们可以看到循环将采取n * (1 + 1/2 + 1/3 + ... + 1/n)
步骤。这是一个有界谐波系列。正如this Math Stack Exchange article所示,就n
而言,上述表达式没有封闭形式。但是,正如this SO article所示,有O(n*ln(n))
的上限。
因此,两个循环的运行时间为O(n*ln(n))
。
答案 1 :(得分:0)
我认为时间复杂度为O(n*log(n))
。原因如下:
让我们选择一些任意自然数i,看看内循环对于给定i有多少步。好吧,对于这个我,你将从j = 1到j&lt; = n,其间跳跃为i。所以基本上你在做这个总结的步骤很多:
summation = 1 + (1+i) + (1+2i) + ... (1+ki)
其中k是最大整数,使得1 + ki <= n。也就是说,k是步数,这就是我们想要解决的问题。那么我们可以在平等中求解k,从而产生k <= (n-1)/i
,从而k = ⌊(n-1)/i⌋
。也就是说,k是(n-1)/i
的floor函数/整数除法。由于我们处理的是时间复杂性,因此这个楼层函数并不重要,所以为简单起见我们只会说k = n/i
。这是内循环对给定i所采取的步数。所以我们基本上需要将所有这些添加到i = 1到i&lt; = n。
所以numsteps将是这样的补充:
numsteps = n/1 + n/2 + n/3 + ... n/n
= n(1 + 1/2 + 1/3 + ... 1+n)
所以我们需要找到1 + 1/2 + ... 1 / n的总和来完成这个。这笔钱实际上并没有很好的封闭形式,但大约是ln(n)
。您可以阅读有关此here的更多信息。你也可以从integral from 1 to n of 1/x is ln(n)
开始猜测这个。同样,由于我们处理时间复杂性,我们可以使用ln(n)来表示其复杂性。因此我们有:
numsteps = n(ln(n))
所以时间复杂度为O(n*log(n))
。
编辑:我的不好,我正在计算总和:P