簡體   English   中英

減少算法的時間復雜度

[英]Reducing time complexity of an algorithm

這是一項從Codility中提取的任務,需要O(n)復雜性。 盡管我已經解決了給出正確結果的任務,但是時間復雜度是O(n * n)。 希望對解釋如何將復雜度降低到O(n)有幫助。

任務描述:

給出了一個由N個整數組成的非空零索引數組A。 數組A代表磁帶上的數字。

任何整數P,例如0 <P <N,都會將此磁帶分割為兩個非空部分:A [0],A [1],...,A [P − 1]和A [P],A [ P + 1],...,A [N − 1]。

這兩個部分之間的差為:|(A [0] + A [1] + ... + A [P-1])-(A [P] + A [P + 1] + .. 。+ A [N − 1])|

換句話說,它是第一部分之和與第二部分之和之間的絕對差。

例如,考慮數組A這樣:

A [0] = 3 A [1] = 1 A [2] = 2 A [3] = 4 A [4] = 3

我們可以將此磁帶分成四個位置:

  P = 1, difference = |3 − 10| = 7 P = 2, difference = |4 − 9| = 5 P = 3, difference = |6 − 7| = 1 P = 4, difference = |10 − 3| = 7 

編寫一個函數:

 int solution(vector<int> &A); 

在給定N個整數的非空零索引數組A的情況下,該函數返回可以實現的最小差異。

例如,給定:

A [0] = 3 A [1] = 1 A [2] = 2 A [3] = 4 A [4] = 3

該函數應返回1,如上所述。

假使,假設:

  N is an integer within the range [2..100,000]; each element of array A is an integer within the range [−1,000..1,000]. 

復雜:

  expected worst-case time complexity is O(N); expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments). 

輸入數組的元素可以修改。

My solution:  
int solution(vector<int>& A)
{
    // write your code in C++11
    int result = std::numeric_limits<int>::max();
    int part_1 = 0;
    int part_2 = 0;
    for (auto beg = A.cbegin(), end = A.cend(); beg != prev(end); ++beg)
    { 
        part_1 = accumulate(A.cbegin(),beg + 1,0);
        part_2 = accumulate(beg + 1,end,0);
        int current_result = abs(part_1 - part_2);
        if (current_result < result)
        {
            result = current_result;
        }

    }

    return result;
}

S[i] = sum of the first i elements 您可以使用單個for循環進行計算:

S[0] = A[0]
for (int i = 1; i < n; ++i)
  S[i] = S[i - 1] + A[i]

然后,對於每個索引0 < i < n ,直到i - 1的總和就是S[i - 1] i到數組末尾的總和為S[n - 1] - S[i - 1]

S[n - 1] = A[0] + ... + A[n - 1]
S[i - 1] = A[0] + ... + A[i - 1]

0 < i < n

S[n - 1] - S[i - 1] =  A[0] + ... + A[i - 1] + A[i] + ... + A[n - 1] -
                      (A[0] + ... + A[i - 1])
                    = A[i] + ... + A[n - 1]

在計算S ,運行另一個循環並檢查兩個和之間的差,就像我描述的那樣,它們在O(1)進行計算:

for (int i = 1; i < n; ++i)
{
  sum_left = S[i - 1]
  sum_right = S[n - 1] - S[i - 1]

  // see if |sum_left - sum_right| is better than what you have so far
}

時間復雜度為O(n)因為您只運行兩個for循環,在每次循環中您只執行O(1)操作。 內存復雜度為O(n)因為必須存儲S ,它的大小與輸入的大小相同。

從我們可以做的假設來看,將S聲明為int[n]應該很好。

暫無
暫無

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

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