计算几种方法的运行时间分析

时间:2012-12-05 01:17:28

标签: java performance big-o

我正在准备我的考试并且在运行时分析方面遇到一些麻烦。我有两种方法,我对运行时分析感到困惑:

 public boolean findDuplicates(String [] arr) {
    Hashtable<String,String> h = new Hashtable<String,String>();
    for (int i = 0; i < arr.length; i++) {
         if (h.get(arr[i]) == null)
              h.put(arr[i], arr[i]);
         else
              return true;
         }
    return false;
    }

假设散列函数只对任何键使用O(1),运行时间是否只是O(n),因为在最坏的情况下,运行整个数组?如果每个哈希函数需要持续的时间来评估,我是否会沿着正确的方向思考这个问题?

我遇到的另一个问题似乎要复杂得多,我不确切知道如何处理这个问题。假设这些是arrarlists。

public boolean makeTranslation(List<Integer> lst1, List<Integer> lst2) {
//both lst1 and lst2 are same size and size is positive
     int shift = lst1.get(0) - lst2.get(0);
     for (int i = 1; i < lst1.size(); i++)
          if ( (lst1.get(i) - lst2.get(i)) != shift)
               return false;
     return true;
}

在这种情况下,get操作应该是常量,因为我们只是检索特定的索引值。但是在for循环中,我们都将它与shift进行比较,并且迭代所有元素。这究竟会如何转化为运行时间?

非常感谢一个有用的解释,因为我最难理解运行时分析而不是本课程中的任何内容,而我的决赛将在下周进行。

4 个答案:

答案 0 :(得分:1)

简短回答:两种方法都具有O(n)的时间复杂度。

对于哈希,显然getput操作都需要一段时间。

对于列表,如果使用ArrayList实现(很可能),get方法也需要恒定时间。这是因为Java中的ArrayList是由数组支持的List

标准Java库中的ArrayList.get(index)代码:

public E get(int index) {
    RangeCheck(index);
    return (E) elementData[index];
}

RangeCheck可能进行了两次比较,即恒定时间。从array返回值显然是恒定的时间。因此,get的{​​{1}}方法需要不变的时间。

至于你在OP中提到的具体问题:

  

但是在for循环中,我们都将它与shift相比较   迭代所有元素。这究竟是如何转化为运行   时间?

ArrayList需要一段时间。 lst1.get(i)需要一段时间。因此,lst2.get(i)需要恒定的时间。同样适用于lst1.get(i) - lst2.get(i)。这个想法是恒定数量的恒定时间操作的总和仍然是恒定的时间。由于循环迭代最多(lst1.get(i) - lst2.get(i)) != shift次,因此总时间为n,即O(n),其中C是常数。

而且......在最后一次之前对the big O notation进行简要回顾是绝对不会伤害的。)

答案 1 :(得分:0)

Big-O表示法不是很准确,因为您省略了常数因子和低阶项。因此,即使你有2次常数运算n次,它仍然是O(n)。实际上,它将是(1 + 1)n = 2n,但在ordo-notation中我们将它向下舍入(即使它是10000n)。因此,对于这两种情况,运行时间将为O(n)。

实际上,我建议在最坏的情况下输入每个循环和每个操作的成本。从最里面的嵌套级别开始并向外相乘(只有每个级别的最高成本)。

例如:

for (int i = 0; i<n; i++) { //n times
    //log n operation
    for (int i = 0; i<n; i++) { //n times
        //constant operation
    }
}

这里,我们有n *(log(n)+ n * 1)= O(n * n)为n> log(n)

答案 2 :(得分:0)

通常,O()表示算法的复杂性,通常是操作的数量,假设每个操作的成本是恒定的。例如 O(1000n) < / strong>类似于编写 O(n) ,因为每个操作都花费 1000 ,并且有 n 操作。

因此假设 获取 put 对于每个值都是常量(取决于库实现),时间两者都是 O(n) 。 有关更多信息,请参阅 http://en.wikipedia.org/wiki/Big_O_notation

答案 3 :(得分:0)

值得回应,但这两项操作都是 O(n)(对于#2,这是最糟糕的情况)。需要注意的关键是每次迭代完成的关键操作数量。

对于您的第一个片段,Hashtable有点像红色鲱鱼,因为访问时间不会是循环中最大的操作。情况也是如此,因为Hashtable只是new'd,您总是 n 元素插入其中。

对于你的第二个片段,你有机会提前结束。如果下一个元素的差异不是shift,那么您在那里返回false然后,这只是一个操作。在最糟糕的情况下,您将浏览所有 n 并返回。