Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 算法复杂度:从开始迭代数组是否与从结束迭代数组相同?_Java_Algorithm - Fatal编程技术网

Java 算法复杂度:从开始迭代数组是否与从结束迭代数组相同?

Java 算法复杂度:从开始迭代数组是否与从结束迭代数组相同?,java,algorithm,Java,Algorithm,在一次采访中,我被问及以下问题: public class Main { public static void main(String[] args) { // TODO Auto-generated method stub int [] array = new int [10000]; for (int i = 0; i < array.length; i++) { // do calculations } for (i

在一次采访中,我被问及以下问题:

public class Main {

public static void main(String[] args) {
    // TODO Auto-generated method stub

    int [] array = new int [10000];

    for (int i = 0; i < array.length; i++) {
       // do calculations   
    }

    for (int x = array.length-1; x >= 0; x--) {
       // do calculations   
    }


}
公共类主{
公共静态void main(字符串[]args){
//TODO自动生成的方法存根
int[]数组=新int[10000];
for(int i=0;i=0;x--){
//计算
}
}
}

从末尾还是从开头迭代数组是一样的?根据我的理解,这是相同的,因为复杂性是恒定的,即O(1)?我说得对吗

还有人问我,与java中的其他集合(例如LinkedList)相比,ArrayList的复杂性如何

谢谢。

对于一个数组,这两种情况下都是O(n),因为有n次迭代,每一步都需要O(1)(假设循环中的计算需要O(1))。特别是,获取长度或大小通常是数组或ArrayList的O(1)操作

从末尾进行迭代的一个典型用例是删除循环中的元素(否则可能需要更复杂的计算,以避免跳过元素或在末尾之外进行迭代)

对于链表,第一个循环通常是O(n²),因为确定链表的长度通常是一个O(n)操作,没有额外的缓存,并且每次检查退出条件时都会使用它但是,java.util.LinkedList显式跟踪长度,因此java中的链表的总长度为O(n)


如果使用计算中的索引访问链表中的元素,这将是一个O(n)操作,总共产生O(n²)。

由于CPU预取特性,可能存在差异

根据计算理论,两个方向的循环之间没有区别。但是,根据运行代码的CPU所使用的预取器的类型,在实践中会有一些差异

例如,Sandy Bridge Intel处理器有一个仅用于数据的预取器(而指令可以在两个方向上预取)。这将有助于从一开始就进行迭代(因为将来的内存位置会预取到一级缓存中),而从最后进行迭代将导致很少甚至没有预取,因此会有更多对RAM的访问,这比访问任何CPU缓存都慢得多

这里有一个关于前向和后向预取的更详细的讨论

从末尾还是从开头迭代数组是一样的?根据我的理解,这是相同的,因为复杂性是恒定的,即O(1)?我说得对吗

从理论上讲,是的,从结尾和开始迭代数组是一样的。
时间复杂度为O(10000),该时间复杂度是恒定的,因此假设循环体具有恒定的时间复杂度。但值得一提的是,常数10000可以提升为变量,称之为
N
,然后可以说时间复杂度为O(N)

还有人问我,与java中的其他集合(例如LinkedList)相比,ArrayList的复杂性如何

在这里,您可以找到ArrayList和LinkedList时间复杂度之间的比较。有趣的方法有
add
remove
get

此外,LinkedList中的数据不是连续存储的。但是,ArrayList中的数据是连续存储的,而且ArrayList使用的空间比LinkedList少
祝你好运

开始和开始之间的区别是什么?如果do计算部分是O(1),那么复杂度显然是O(n),n是数组中的元素数。访问一个数组元素需要固定的时间O(1),并且您有n个数组元素。如果您必须遍历整个列表,这并不重要。如果在您的计算中,您有很好的机会退出(通过中断),则必须选择最可能的解决方案。CPU预取特性可能会有所不同。
array.length
在第一个示例中调用10000次,在第二个示例中调用一次,至少在理论上是这样。它可能会被优化。获取LinkedList的大小是O(1)。列表有一个保持其大小的字段。它不会反复去了解它。然而,在LinkedList中,Doing list.get(i)的开销非常大,因为它需要迭代。这就是为什么应该使用迭代器遍历列表,而不是通过元素的索引访问元素。