簡體   English   中英

數組算法及其時間復雜度分析

[英]Analysis of array algorithm and its time complexity

我應該分析這段代碼,並講一些有關其時間復雜度的信息,但是我很難理解代碼本身的作用,它如何改變數組a?

我也不理解以下兩個操作:1)foobar [a [i]] ++; 因此,您將foobar中的零替換為數組a的元素嗎? 但是++的作用是什么?

2)a [outPos ++] = 1; 這將首先增加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;
}

就時間復雜度而言,我認為是O(n ^ 2)。 前兩個for循環以恆定的時間運行。 但是在我看來,第三個嵌套循環的最壞情況是foobar中的最后一個元素很大,然后將是平方的?

它是Counting Sort的實現,

其中a[]存儲要排序的數組, ba[]的最大整數

foobar[]是大小為b的計數數組

N = sizeof(a), M = b對於常用符號, N = sizeof(a), M = b

前兩個循環:

  1. 將計數數組初始化為零O(M)
  2. 計算元素,說a[]是否有3個'10', foobar[10] = 3O(N)

棘手的第三循環:

  1. 外環,無疑, O(M)
  2. 內循環,您必須考慮可以增加j的總時間(最大) :即Sum(foobar[]) = sizeof(a) = N ,因此在整個外循環迭代過程中,此循環確實是必然的最多執行N次。 因此,兩個循環整體都是O(N+M) ,而不是直觀的O(NM)

因此總復雜度為: O(N) + O(M) + O(N+M) = O(N+M)

如果您發現難以理解第三個循環的復雜性,請使用以下技巧:

這是一個零和游戲。 如果某些foobar[z] is large ,則有很多foobar[j] = 0 ,這幾乎意味着跳過此類i的內部循環。 否則,所有foobar[j]大小均約為平均大小。

很難對i每個迭代進行分析,但是很容易分析整個內部循環,因為我們知道foobar[]總和是一個常數。

這看起來像是計數排序實現。 考慮到N(項數)是數組a的長度,M(最大可能項)是b ,其時間復雜度為O(N + M)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM