【问题标题】:Analysis algorithm Best, Worst and Average case分析算法 最佳、最坏和平均情况
【发布时间】:2019-07-06 17:48:19
【问题描述】:

我想知道 find 和 replaceAll 方法的最佳、最差和平均情况以及增长函数,它基本上是在以下代码中数组大小大于零的每种情况下执行的语句数

/**
 * Return index where value is found in array or -1 if not found.
 * @param array ints where value may be found
 * @param value int that may be in array
 * @return index where value is found or -1 if not found
 */
public static int find(int[] array, int value) {
    for (int i = 0; i < array.length; i++) {
        if (array[i] == value) {
            return i;
        }
    }
    return -1;
}

/**
 * Replace all occurrences of oldValue with newValue in array.
 * @param array ints where oldValue may be found
 * @param oldValue value to replace
 * @param newValue new value
 */
public static void replaceAll(int[] array, int oldValue, int newValue) {
    int index = find(array, oldValue);
    while (index > -1) {
        array[index] = newValue;
        index = find(array, oldValue);
    }
}

【问题讨论】:

  • 您认为两种方法中最好的最坏情况和平均情况是什么?您为什么这么认为?
  • 对于 find():1- 如果元素在数组的第一个索引中,则为最佳情况 2- 最坏情况:如果该元素在数组中不存在。 3-平均:如果元素在数组的中间。这就是我的想法。我也想找到增长函数
  • 编辑您的问题以包含该问题以及您要查找的“增长函数”是什么?

标签: java algorithm replace find


【解决方案1】:

您的运行时位于O(n^2)

  • 最佳情况:该数组恰好包含一项与您要替换的值相等的项。此项目也是数组中的第一项。在n 迭代中运行
  • 最坏情况:数组中的所有项目都等于您要替换的值。这将在 n^2 迭代中运行

一个简单的优化,使它在O(n)

如果你想在O(n)中做,你需要在使用find时传递起始索引,这样你就不必从数组的开头重复搜索

public static int find(int[] array, int value, int start) {
    for (int i = start; i < array.length; i++) {
        if (array[i] == value) {
            return i;
        }
    }
    return -1;
}

public static void replaceAll(int[] array, int oldValue, int newValue) {
    int index = find(array, oldValue);
    while (index > -1) {
        array[index] = newValue;
        index = find(array, oldValue, index);
    }
}

【讨论】:

    【解决方案2】:

    这是用于 find(...) 方法的

    你很容易知道最好和最坏的情况:

    最好的情况是您要搜索的元素是数组中的第一个元素。在这种情况下,只需 1 次迭代即可找到您的元素,O(1) 常数时间。

    同样,最坏的情况是当您要搜索的元素在数组中不存在时,因此您遍历整个数组却一无所获。在这种情况下,它需要 n 次迭代(其中 n 是数组的大小),O(n) 线性时间。

    大多数情况下,最坏的情况很容易确定。您可以简单地查看嵌套循环。如果您有x 数量的嵌套循环,其中所有循环都以线性时间在数组上迭代,那么您的时间复杂度为 O(n^x)。所以在 replaceAll(...) 中,您有 2 个嵌套循环(whilefor 来自您的 find(...) 方法)意味着复杂性是 O(n^2) replaceAll(...) 的最坏情况

    对于一般情况:

    我为你的find(...)函数写了一个测试:

    public static void main(String[] args) {
    
        int iterationsTotal = 0;
        int timesTested = 100000;
        //Test 1000 times
        for(int i = 0; i < timesTested; i++) {
    
            int n = 100; //Array size to test 
            int[] array = new int[n];
            //Populate the array
            int j = 0;
            for(j = 0; j < array.length; j++) {
                array[j] = (int)(Math.random() * 100);
            }
            //You can search for any number, even 99. It will always result in 25 average.
            iterationsTotal += find(array, 5);
        }
    
        System.out.println(iterationsTotal / timesTested);
    
    }
    

    上面的代码测试了你的 find 函数 100,000 次。它计算它所花费的平均迭代次数,每次我运行它时,它通常会达到约 25 次。使用大小为 100 的数组,平均 25 次迭代来找到您正在搜索的元素。这就是O(n/4),其中 n = 数组的大小,在本例中为 100。这与 O(n) (Why to ignore the constants in computing the running time complexity of an Algorithm) 一样好。因此,find(...) 算法的平均情况为 O(n)。你可以对replaceAll(...)做同样的事情

    【讨论】:

    • 能否单独指定每个案例
    • 好的,我已经添加了最好/最坏的情况
    • 我说的是find方法。我已经编辑来解释这一点,并且还提到了 replaceAll 的最坏情况时间复杂度。
    • find() 方法:最佳情况:我们将执行 3 条语句 最坏情况:3n+2 条语句 平均语句:是 (3n/2)+3 条语句。这是正确的
    • 你不必关心 3 个语句。你关心的是循环,这是最耗时的。另外,你不要写O(3n+2) 3 和2 是微不足道的。该表达式的显着部分是 n,它可能会变得非常大,具体取决于数组的大小。只有当 n 很大时,该表达式的值才会变大。因此,我们只写O(n),归根结底,时间复杂度线性依赖于n。 3 和 2 只会增加这么多。
    【解决方案3】:

    查找

    • 我们最多只能在第一个位置找到所需的序列,因此:Ω(1)
    • 在最坏的情况下,我们会在最后找到所需的序列:O(n)
    • 平均值:Θ(n)

    全部替换

    • 最坏的情况是 O(n^2),因为它需要搜索所有字符以找到所需的替换。

    增长函数?

    • 上面的代码中没有任何增长方法,所以我将为您提供复制数组的时间复杂度。 所有情况都是线性的O(n)

    我希望这会有所帮助。

    【讨论】:

    • ReplaceAll 最坏情况应该是 O(n^2)。
    • 这不是真的。如果你有一个像[1, 1, 1, 1, 1, 1] 这样的数组,并且你想用2 替换1,这将在 O(n^2) 中运行。因为每次替换都会从头开始循环
    • 一般的经验法则是当你有嵌套循环时,最坏情况的时间复杂度将是 O(n^2)
    • 天哪。我以为他指的是Java的replaceAll实现。我相信它是 O(n) 对吧?
    • 增长函数,我的意思是在每种情况下如何执行语句
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多