简体   繁体   English

数组算法及其时间复杂度分析

[英]Analysis of array algorithm and its time complexity

I'm supposed to analyse this code and say something about its time complexity, but I am having trouble understanding what the code itself does, how does it change array a? 我应该分析这段代码,并讲一些有关其时间复杂度的信息,但是我很难理解代码本身的作用,它如何改变数组a?

I also don't understand the following two operations: 1) foobar[a[i]]++; 我也不理解以下两个操作:1)foobar [a [i]] ++; So you replace the zeros in foobar with elements of array a? 因此,您将foobar中的零替换为数组a的元素吗? But what does the ++ do? 但是++的作用是什么?

2) a[outPos++]=1; 2)a [outPos ++] = 1; This increments outPos first, and leaves a[0] unchanged during the whole for loop? 这将首先增加outPos,并在整个for循环中使a [0]保持不变?

public static void foo(int[] a, int b) {
    int [] foobar = new int[b+1];
    for (int i = 0; i<foobar.length; i++)
        foobar[i]=0;
    for (int i = 0; i<a.length; i++)
        foobar[a[i]]++;
    int outPos = 0;
    for (int i=0; i<foobar.length; i++)
        for (int j=0; j<foobar[i]; j++)
            a[outPos++]=i;
}

As far as time complexity goes, I think it's O(n^2). 就时间复杂度而言,我认为是O(n ^ 2)。 The first two for loops run in constant time. 前两个for循环以恒定的时间运行。 But the worst case of the third nested loop seems to me that the last element in foobar is big, and then it would be quadratic? 但是在我看来,第三个嵌套循环的最坏情况是foobar中的最后一个元素很大,然后将是平方的?

It is an implementation of Counting Sort , 它是Counting Sort的实现,

Where a[] stores the array to be sorted and b is the maximum integer in a[] 其中a[]存储要排序的数组, ba[]的最大整数

foobar[] is the counting array which is of size b foobar[]是大小为b的计数数组

Let N = sizeof(a), M = b for common notation, N = sizeof(a), M = b对于常用符号, N = sizeof(a), M = b

The first two loops: 前两个循环:

  1. Initializing counting array to zeros O(M) 将计数数组初始化为零O(M)
  2. Count the elements, say if there is 3 '10's in a[] , foobar[10] = 3 , O(N) 计算元素,说a[]是否有3个'10', foobar[10] = 3O(N)

The tricky third loop: 棘手的第三循环:

  1. Outer loop, without doubt, O(M) 外环,无疑, O(M)
  2. Inner loop, you have to consider the total(maximum) # of time that j can be increased : which is Sum(foobar[]) = sizeof(a) = N , so indeed this loop, throughout whole outer loop iteration, is bound to be executed N times at most. 内循环,您必须考虑可以增加j的总时间(最大) :即Sum(foobar[]) = sizeof(a) = N ,因此在整个外循环迭代过程中,此循环确实是必然的最多执行N次。 So both loops as a whole is O(N+M) , instead of intuitively O(NM) 因此,两个循环整体都是O(N+M) ,而不是直观的O(NM)

So total complexity is: O(N) + O(M) + O(N+M) = O(N+M) . 因此总复杂度为: O(N) + O(M) + O(N+M) = O(N+M)

A tips if you found the third loop complexity is hard to understand, think in a way like this: 如果您发现难以理解第三个循环的复杂性,请使用以下技巧:

It is a 0-sum game. 这是一个零和游戏。 If some foobar[z] is large , then there is many foobar[j] = 0 which almost means skip the inner loop for such i . 如果某些foobar[z] is large ,则有很多foobar[j] = 0 ,这几乎意味着跳过此类i的内部循环。 Otherwise, all foobar[j] will be about at average size. 否则,所有foobar[j]大小均约为平均大小。

It is hard to analysis per iteration of i , but it is easy to analysis the inner loop as a whole, as we know the total sum of foobar[] is a constant. 很难对i每个迭代进行分析,但是很容易分析整个内部循环,因为我们知道foobar[]总和是一个常数。

This looks like a counting sort implementation. 这看起来像是计数排序实现。 Considering that N (number of items) is the length of array a , and M (largest possible item) is b , its time complexity is O(N+M). 考虑到N(项数)是数组a的长度,M(最大可能项)是b ,其时间复杂度为O(N + M)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM