[英]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.