Javascript 嵌套在while循环中的for循环的时间复杂度是多少?

Javascript 嵌套在while循环中的for循环的时间复杂度是多少?,javascript,time-complexity,big-o,computer-science,Javascript,Time Complexity,Big O,Computer Science,我试图优化一个函数。我相信这个嵌套for循环是二次的,但我不是肯定的。我已经重新创建了下面的函数 const bucket=[[“e”、“f”]、[]、[“j”]、[]、[“p”、“q”] 设TotaletterSiwantBack=4; //我从桶底开始 函数produceLetterArray(桶、限制){ 让结果=[]; 让countOfLettersAccumulated=0; 设i=bucket.length-1; 而(i>0){ if(桶[i]。长度>0){ bucket[i].f

我试图优化一个函数。我相信这个嵌套for循环是二次的,但我不是肯定的。我已经重新创建了下面的函数

const bucket=[[“e”、“f”]、[]、[“j”]、[]、[“p”、“q”]
设TotaletterSiwantBack=4;
//我从桶底开始
函数produceLetterArray(桶、限制){
让结果=[];
让countOfLettersAccumulated=0;
设i=bucket.length-1;
而(i>0){
if(桶[i]。长度>0){
bucket[i].forEach((字母)=>{
if(累计的字符数===总计字符数){
回来
}
结果:推(信);
累积的字母数++;
})
}
我--;
}
返回结果;
}

日志(produceLetterArray(bucket,TotaletterSiwantBack))这在技术上是线性的,n是矩阵中的元素总数。这是因为退出条件是bucket的长度,对于bucket中的每个数组,检查countOfLettersAccumulated是否等于totallettersawntback。不断关注价值观

如果你正在寻找一个与你的矩阵的维度相匹配的答案,它会变得复杂得多,因为看起来bucket的维度是不固定的

您可以通过在bucket foreach之外添加一个额外的检查(如果countOfLettersAccumulated等于 然后你休息一下。

这是一个针对此类问题的技巧。对于要分析其复杂性的代码,只需在假设不存在其他语句的最坏情况下编写执行每条语句所需的时间。注意以
#操作最坏情况开始的注释:

对于给定代码:

while(i > 0){ //#operations worst case: bucket.length
  if(bucket[i].length > 0){ //#operations worst case:: 1
    bucket[i].forEach( (letter) =>{  //#operations worst case: max(len(bucket[i])) for all i
    if(countOfLettersAccumulated === totalLettersIWantBack){ //#operations worst case:1
      return;
    }
    result.push(letter); //#operations worst case:1
   countOfLettersAccumulated++; //#operations worst case:1
    })
  }
  i--; ////#operations worst case:: 1
}
我们现在可以将所有最坏情况时间相乘(因为它们都可以在最坏情况下实现,所以您可以始终设置TotaletterSiwantBack=10^9),以获得代码段的
O
复杂性:

复杂性=
O(bucket.length*1*max(len(bucket[i]))*1*1*1)

=
O(bucket.length*max(len(bucket[i]))

如果每个bucket[i]的长度是一个常数,
K
,那么您的复杂性将降低到:
O(K*bucket.length)
=
O(bucket.length)


请注意,推送操作的复杂性可能不会随着元素数量的增加而保持不变(最终,运行时将需要为添加的元素分配空间,并且可能必须移动所有现有元素)

< p>此是否为二次取决于你所考虑的n和桶是如何组织的。如果n是字母的总数,那么运行时间由桶中的容器数量决定,如果大于N,或者它被桶中的字母数所限制,如果n大于,那么在任一情况下,搜索时间都会增加。s与更大的界限呈线性关系,如果一方支配另一方,则时间复杂度为O(N)。这实际上是一个带“转折”的线性搜索在这种情况下,将线性搜索压缩并隔开不会改变时间复杂度。一段代码中存在多个循环并不仅仅使其成为非线性。再次以线性搜索为例。我们搜索列表,直到找到最大的元素

//12个元素
var数组=[0,1,2,3,4,5,6,7,8,9,10,11];
var行=3;
var-cols=4;
最大var=-1;
对于(变量i=0;i最大){
最大=已检查;
}      
} 
}
log(“找到最大的数字(十一):“+maxist.toString());
我喜欢复杂度分析

只是想添加可能的优化解决方案

UPD
.push
()比
.concat
()

这里还有一个测试

const bucket=[[“e”、“f”]、[]、[“j”、“m”、“b”]、[]、[]、[“p”、“q”]
设TotaletterSiwantBack=4;
//我从桶底开始
函数produceLetterArray(桶、限制){
让结果=[];
对于(设i=bucket.length-1;i>0&&result.lengthconsole.log(produceretterArray(bucket,totalettersiwantback));
如果我们无法运行它,为什么要将其作为一个片段?@Vallentin对此表示抱歉。它现在可以执行了。感谢您提供的详细答案。所以您说最好的情况是O(n)?@colbisaurusrex,当然。是的,如果每个子阵列中的元素数是常数,那么最坏的ase实际上是O(N),其中N=外部阵列(bucket)中的元素数。另外,请注意Big-O(或最坏情况下的时间复杂度)实际上,它告诉您代码所用的时间是如何随着输入的变化而变化的。例如,冒泡排序是O(n^2)。如果4个元素需要4秒,那么8个元素需要16秒。您可以将其视为每个算法或函数的排名。谢谢您的回答。concat是否将时间复杂性设为O(n^2)是的,伙计,你说得对。我不知道=)我已经更新了答案。