Algorithm 该算法的时间复杂度为两个for循环

Algorithm 该算法的时间复杂度为两个for循环,algorithm,time-complexity,nested-loops,binary-search,logarithm,Algorithm,Time Complexity,Nested Loops,Binary Search,Logarithm,你能给我解释一下如何找到这个的时间复杂度吗 sum1=0; for(k=1;k<=n;k*=2) for(j=1;j<n;j++) sum++ 但我不能把它概括起来。 请有人给我解释清楚。 我甚至检查了其他类似类型的查询,如: 接着说 1,2,4,8...n so it will be 2^n nlogn 但我不明白。 我不知道他们怎么说。 请适当解释如何一步一步地计算 谢谢:)为了获得两个循环的全部复杂性,需要将外部循环的复杂性乘以内部循环的复杂性。这是通过思考当

你能给我解释一下如何找到这个的时间复杂度吗

sum1=0;
for(k=1;k<=n;k*=2)
  for(j=1;j<n;j++)
     sum++
但我不能把它概括起来。 请有人给我解释清楚。 我甚至检查了其他类似类型的查询,如: 接着说

1,2,4,8...n so it will be
2^n
nlogn
但我不明白。 我不知道他们怎么说。 请适当解释如何一步一步地计算


谢谢:)

为了获得两个循环的全部复杂性,需要将外部循环的复杂性乘以内部循环的复杂性。这是通过思考当n变得非常大时(从技术上讲,当n趋于无穷大时)会发生什么来实现的。您总共需要对sum或循环变量执行多少操作

在这种情况下,随着k的指数增长,外部循环执行
log(n)
次。因为k在外循环的每次迭代中都是双倍的,所以这意味着它以2^k的形式增长,直到2^k变成n。关于像这样乘以循环变量的注释。根据您在评论中提出的问题,如果将k乘以3,您仍然会得到
log(n)
,但它将使用base-3记录,而不是使用base-2记录。渐近地,日志的基数是不相关的,所以您可以简单地说它是log(n),忽略基数。因此,第一个循环具有
O(log(n))
复杂性。内部循环仍然是线性的(运行n次),因此如果将它们相乘,则会得到
O(n*log(n))
复杂度


总之:O(nlogn)为了获得两个循环的全部复杂性,需要将外循环的复杂性乘以内循环的复杂性。这是通过思考当n变得非常大时(从技术上讲,当n趋于无穷大时)会发生什么来实现的。您总共需要对sum或循环变量执行多少操作

在这种情况下,随着k的指数增长,外部循环执行
log(n)
次。因为k在外循环的每次迭代中都是双倍的,所以这意味着它以2^k的形式增长,直到2^k变成n。关于像这样乘以循环变量的注释。根据您在评论中提出的问题,如果将k乘以3,您仍然会得到
log(n)
,但它将使用base-3记录,而不是使用base-2记录。渐近地,日志的基数是不相关的,所以您可以简单地说它是log(n),忽略基数。因此,第一个循环具有
O(log(n))
复杂性。内部循环仍然是线性的(运行n次),因此如果将它们相乘,则会得到
O(n*log(n))
复杂度


总之:O(nlogn)
k
呈指数增长,因此需要
O(logn)
时间才能达到
n
。检查的定义。那是你的外环


内部循环是一个简单的
O(n)
k
指数增长,因此需要
O(logn)
时间才能达到
n
。检查的定义。那是你的外环


内环是一个简单的
O(n)

,因为内环是

for(j=1;j<n;j++)
for(j=1;j<k;j++)
请注意,这是一个系列,而不是一个序列。事实上,这是众所周知的。该系列的总和由下式给出:

a(1 - r^(i + 1))/(1 - r) 
其中a=1,r=2,如果用log(n)代替i(前面分析的log(n),则得到

那是

2*n - 1

因为内环是

for(j=1;j<n;j++)
for(j=1;j<k;j++)
请注意,这是一个系列,而不是一个序列。事实上,这是众所周知的。该系列的总和由下式给出:

a(1 - r^(i + 1))/(1 - r) 
其中a=1,r=2,如果用log(n)代替i(前面分析的log(n),则得到

那是

2*n - 1

考虑到您的问题结构:

sum1=0;
for(k=1;k<=n;k*=2)  // <-- Takes 1+1/2+1/2^2+1/2^3...+1/2^n = O(log(n)) time
   for(j=1;j<n;j++)  // <-- Takes 1+2+3+...+n = O(n) time
      sum++
换句话说,每次都要丢弃一半的元素。话虽如此,您实际上是在中搜索大小为n的数组

1+(1/2)+(1/2^2)+(1/2^3)+...+(1/2^n) time = log(n) time
日志(n)是怎么来的?

以二叉树为例,在每个节点上,我们都会分支为两个节点,这两个节点可以表示为递归关系:

T(n) = 2T(n/2)
当搜索空间减少2时,当搜索空间等于
1
时,当我们从根开始走得更远时,我们必须达到边界条件。深度为k的搜索空间大小为
n/2^k
(类似于我们上面看到的)

对搜索空间进行等值后,我们的方程变为:

n/2^k = 1
=> n = 2^k

Taking log on both sides:
=> log n = k log 2
=> log n/ log 2 = k

Rearranging:
k = log n base 2.
所以在叶节点,我们将遍历的二叉树的高度是log(n)base 2。在我们的例子中,我们将搜索空间分为两个部分,并以二的幂遍历搜索空间,到达
log(n)
time中的结束元素


鉴于您的问题结构,两个循环的总体时间复杂度顺序为n*logn=
O(nlog(n))

sum1=0;
for(k=1;k<=n;k*=2)  // <-- Takes 1+1/2+1/2^2+1/2^3...+1/2^n = O(log(n)) time
   for(j=1;j<n;j++)  // <-- Takes 1+2+3+...+n = O(n) time
      sum++
换句话说,每次都要丢弃一半的元素。话虽如此,您实际上是在中搜索大小为n的数组

1+(1/2)+(1/2^2)+(1/2^3)+...+(1/2^n) time = log(n) time
日志(n)是怎么来的?

以二叉树为例,在每个节点上,我们都会分支为两个节点,这两个节点可以表示为递归关系:

T(n) = 2T(n/2)
当搜索空间减少2时,当搜索空间等于
1
时,当我们从根开始走得更远时,我们必须达到边界条件。深度为k的搜索空间大小为
n/2^k
(类似于我们上面看到的)

对搜索空间进行等值后,我们的方程变为:

n/2^k = 1
=> n = 2^k

Taking log on both sides:
=> log n = k log 2
=> log n/ log 2 = k

Rearranging:
k = log n base 2.
所以在叶节点,我们将遍历的二叉树的高度是log(n)base 2。在我们的例子中,我们将搜索空间分为两个部分,并以二的幂遍历搜索空间,到达
log(n)
time中的结束元素


这两个循环的总体时间复杂度的顺序是n*logn=
O(nlog(n))

,但我的文章说:时间复杂度是nLogn。这就是为什么confused@JerryCoffin:文本显示:#ru