演算法導論中的乙個題目,上
次面試題中被擴充套件到了二維和二維環形陣列,記錄下以供參考。
一、 一維連續子陣列 最大和
問題描述:給定乙個一維陣列,求其中連續子陣列和的最大值。
樣例輸入:
樣例輸出:9 // 1 + 5 + -3 + 6
方法1:分治法,也是演算法導論中介紹的一種方法。選取陣列的中間元素a[n/2],那麼子陣列要麼經過中間元素,要麼在a[0]和中間元素之間,要麼在中間元素和a[n]之間。如果經過中間元素,從中間元素開始向兩側尋找最大和子陣列,兩個陣列合併即可得到跨中間元素的最大和子陣列。遞迴求解兩側最大子陣列情況。
時間複雜度分析:t( n ) = 2*t( n/2 ) + θ(n) ------->
θ(n logn)
這種演算法時間複雜度為n logn,雖然相比蠻力法更快,但依然不是最優。因為每次遞迴求解子陣列和時,都會產生重複求解的問題。
下列方法2、3使用動態規劃對此問題進行改進,時間複雜度達到 o( n )。
方法2:動態規劃。一維陣列的子陣列兩端都是不固定的,我們可以先假設一端已經確定位置,那麼只需確定另一端的位置即可。用輔助陣列 c[r] 儲存 a[0] -> a[r] 之間最大連續子陣列和,其中 a[r] 是子陣列的乙個端點。當填充完c[0] -> c[n-1]後,c陣列中的最大值即是我們要求的結果。
狀態轉移方程:c[r] = max( 0, c[r-1] ) + a[r] // a[r]為乙個端點,如果c[r]非0,那麼最大值應為 c[r] + a[r]
這裡使用c陣列來儲存狀態,實際程式中只需要乙個變數即可。因為c的後乙個狀態只與前乙個狀態有關。
#include int getmaxsubarraysum( int *a, int n)
return max_sum;
}int main()
; printf( "%d", getmaxsubarraysum( a, 5));
}
方法3:動態規劃。這種方法與上一種方法類似,假設子陣列一端已經確定位置,然後進行另一端位置的確定,不過這裡使用的狀態轉移方程不同。用輔助陣列s[i]記錄 a[0] -> a[r] 元素之和,min記錄 s[0] 到 s[r-1] 的最小值。那麼 c[r] = s[r] - min 即以 a[r] 結束的子陣列的最小值。最後求得c陣列中的
最大值即結果。
同方法二,s和c只需要取兩個變數即可,沒有必要設定為兩個陣列。
int getmaxsubarraysum( int *a, int n)
return max_sum;
}
因為至少要遍歷陣列一遍,因此方法2、3的時間複雜度已達到最低 o( n ) 要求。
二、 一維環形子陣列 最大和
這裡說的一維環形子樹組是指子陣列可以跨越a[0] 與 a[n-1]形成子陣列。例如輸入為,那麼輸出應為10,即子陣列為。
解決方法:分治+動態規劃。一維環形子陣列相比於前面只是增加了環形而已,因此我們將此問題分解為兩個子問題考慮。第1種情況是子陣列不跨越 a[0]、a[n-1],這種情況是我們上面解決過的;第2種情況是跨越 a[0]、a[n-1],我們可以先求解 a[0] -> a[n-1] 最小和子陣列min_sum,使用陣列總和sum - min_sum即可得到第二種情況的最大值。 然後返回1、2情況較大的值即可。
下面**沿用一的方法2,增加狀態轉移方程 s[r] = min( 0, s[r-1] ) + a[r],s[r] 記錄以 a[r] 結束的最小和子陣列。增加min_sum記錄 子陣列最小和,sum記錄陣列總的和。
#include int getmaxsubarraysum( int *a, int n)
int main()
; printf( "%d", getmaxsubarraysum( a, 5));
}
三、 二維連續子陣列 最大和問題描述:給定乙個二維陣列,求其中連續子陣列和的最大值。
樣例輸入: 1, 5, -3, 6, -7
3, 5, -9, -4, 6
-8, 4, 0, 12, -3
3,-1, 5, -5, 8
樣例輸出:20 // 4, 0, 12, -3
// -1, 5, -5, 8
解決方法:暴力降維法。這種方法時間複雜度為o(n^3),暫時沒有找到時間複雜度更低的方法(理論時間複雜度下限為o(n^2) ),若有時間複雜度更低的方法,還望不吝賜教。
二維子陣列的四面都可以進行擴充套件,如果使用暴力法的話需要 o( n^4) 時間複雜度,因此同上,我們選擇固定其兩端不變化,然後使用 一維陣列 的解決方案進行求解。見下圖:
一維陣列和二維陣列
一維陣列和二維陣列 一維陣列 在程式中可以使用下標變數,即說明這些變數的整體為陣列,陣列的每個變數的資料型別是相同的。當陣列中每個元素都只帶有乙個下標時,稱這樣的陣列為一維陣列。例 int arr 4 這時,我們分析一下 arr arr 1 arr 2 的資料型別 可以看出arr指的是陣列首元素ar...
最大連續子陣列和
題目描述 輸入乙個整形陣列,陣列裡有正數也有負數。陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。求所有子陣列的和的最大值,要求時間複雜度為o n 例如輸入的陣列為 1,2,3,10,4,7,2,5 和最大的子陣列為 3,10,4,7,2 因此輸出為該子陣列的和18。思路 採用貪婪法...
最大連續子陣列和
輸入乙個整形陣列,陣列裡有正數也有負數。陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。求所有子陣列的和的最大值,要求時間複雜度為o n 例如輸入的陣列為1,2,3,10,4,7,2,5,和最大的子陣列為3,10,4,7,2,因此輸出為該子陣列的和18。第乙個想法肯定就是如果能夠把陣...