Java 算法的时间复杂度取决于递增/递减步长部分,而不是实际输入大小?

Java 算法的时间复杂度取决于递增/递减步长部分,而不是实际输入大小?,java,algorithm,input,time-complexity,big-o,Java,Algorithm,Input,Time Complexity,Big O,我正在读这个问题,这句话准确地抓住了我的注意力 注释说,为了实现O(n logn),我们需要外部循环为:for(int i=0;i0;j/=2),这使得嵌套循环域从n到n/2 我知道,要找到时间复杂度,我们需要考虑输入大小和运行计算所需的步骤数,但在我看来,这完全取决于逐步通过部分,以及如何最小化从0到n的步骤数(反之亦然)。我的理解正确吗 如果这是真的,那么将嵌套循环更改为for(int j=n/2;j>0;j--)或for(int j=n/4;j>0;j--)(这将使域分别介于0和n/2或n

我正在读这个问题,这句话准确地抓住了我的注意力

注释说,为了实现O(n logn),我们需要外部循环为:
for(int i=0;i
,嵌套循环为:
for(int j=n;j>0;j/=2)
,这使得嵌套循环域从n到n/2

我知道,要找到时间复杂度,我们需要考虑输入大小和运行计算所需的步骤数,但在我看来,这完全取决于逐步通过部分,以及如何最小化从0到n的步骤数(反之亦然)。我的理解正确吗

如果这是真的,那么将嵌套循环更改为
for(int j=n/2;j>0;j--)
for(int j=n/4;j>0;j--)
(这将使域分别介于0和n/2或n/4之间)仍将保持算法复杂度时间
n*(n/2)或n*(n/4)=n^2

我感谢你的解释

…这使得嵌套循环域:从n到n/2

那不太对。循环仍然从
n
0
;域名没有改变。改变的是它如何到达那里。它不会在每次迭代中减去一个,这意味着需要
n
步。每次迭代将
j
分成两半

在达到0之前,你能将一个数字分成两半多少次?如果从n开始,则需要O(log2n)步

  • 四,→ 2.→ 1.→ 0=3步
  • 八,→ 4.→ 2.→ 1.→ 0=4步
  • 十六,→ 8.→ 4.→ 2.→ 1.→ 0=5步
  • 三十二→ 16→ 8.→ 4.→ 2.→ 1.→ 0=6步
每次你翻倍n,它需要多走一步。经典的指数/对数关系

教训是:在迭代步骤中进行除法有很大的区别

for(int j = n; j > 0; j/=2)       // O(log n)
…并使其处于起始或结束边界:

for(int j = n/2; j > 0; j--)      // O(n/2) = O(n)
for(int j = n; j > n/2; j--)      // O(n/2) = O(n)

在for循环中,每次我们将j的值更新为其先前值的一半


因此,所采取的步骤数将为log(n),域不是n到n/2,而是n到0,因为for循环一直运行到j>0。

“算法的时间复杂度取决于增量/递减步骤部分,而不是实际输入大小?”-是。如果要对输入的所有元素求和,则将是一个线性(
O(n)
)操作。是否有
10
100
100000
元素并不重要。函数保持线性。您只需将这些
10
100
100000
放入函数
f(x)
,并获得
f(10)
f(100)
f(100000)
。感谢您的解释,我们如何采取这些步骤决定了时间复杂性,因为它将设置近似时间(又称数学关系)从n到0需要多少时间?@USR67252它既是域又是“增量”/步骤。
对于(int j=n;j>0;j/=2)
O(logn)
(忽略循环体的复杂性),对于(int j=log2(n);j>0;j-)也是