在有和没有递归的情况下确定时间复杂度

时间:2014-02-03 02:14:33

标签: algorithm data-structures recursion time-complexity

我正在从一本书中学习数据结构。在本书中,他们在本章末尾有伪代码片段,我试图确定时间复杂度。我在理解时间复杂度方面遇到了一些困难。

我有两段代码执行相同的操作,查看数组中的元素是否至少发生3次;但是,一个使用递归,另一个使用循环。我有两个答案;谁能告诉我他们是否正确?

第一种方式(没有递归):

boolean findTripleA(int[] anArray) { 
    if (anArray.length <= 2) { 
        return false; 
    } 
    for (int i=0; i < anArray.length; i++) { 
        // check if anArray[i] occurs at least three times 
        // by counting how often it occurs in anArray 
        int count = 0; 
        for (int j = 0; j < anArray.length; j++) { 
            if (anArray[i] == anArray[j]) { 
                count++; 
            } 
        } 
        if (count >= 3) { 
            return true; 
        } 
    }
    return false; 
}

我认为第一种方式在最佳和最差情况下的时间复杂度为O(n ^ 2),因为没有办法避免内部for循环。

第二种方式(使用递归):

public static Integer findTripleB(int[] an Array) {
    if (anArray.length <= 2) { 
        return false; 
    } 
    // use insertion sort to sort anArray 
    for (int i = 1; i < anArray.length; i++) { 
        // insert anArray[i] 
        int j = i-1; 
        int element = anArray[i]; 
        while (j >= 0 && anArray[j] > element) { 
            anArray[j+1] = anArray[j]; 
            j--; 
        } 
        anArray[j+1] = element; 
    } 
    // check whether anArray contains three consecutive 
    // elements of the same value 
    for (int i = 0; i < anArray.length-2; i++) { 
        if (anArray[i] == anArray[i+2]) { 
            return new Integer(anArray[i]); 
        } 
    } 
    return null; 
} 

我认为第二种方式的最坏情况时间复杂度为O(n ^ 2),最好的情况是O(n),如果数组已经排序并且可以跳过插入排序;但我不知道递归是如何生效的。

1 个答案:

答案 0 :(得分:0)

第一个最好的情况是O(n) - 考虑当首次出现的元素出现3次时会发生什么(它将在外部循环的一次迭代后返回)。

第二个不使用递归,并且您的运行时间是正确的(技术上插入排序不会被“跳过”,但是已经排序的数组上的插入排序的运行时间是O(n) - 只是制作确定我们在同一页面上。)

解决问题的另外两种方法:

  • 使用更好的sorting algorithm排序,例如mergesort 需要O(n log n)最佳和最差情况。

  • 将元素插入hash map元素中进行计数 将采用预期的O(n)最坏情况,O(1)最佳情况。