快要畢業了,逐步把之前做過的一些演算法和資料結構,專案相關資料總結整理一下,一來溫習一下之前的知識,二來記錄下學習點滴,方便之後的學習。
[plain]view plain
copy
print?
題目描述:給定乙個整數陣列,陣列中有正數也有負數,陣列中連續的乙個或者多個整數組成乙個子陣列,每個子陣列都有乙個和,求給定陣列的最大子陣列和。也成為「最大子段和」問題。要求時間複雜度為o(n).
該題目是乙個簡單的dp問題。演算法的思路很多,但是如果要滿足時間複雜度為o(n)。一般的演算法是達不到的。
dp解決該問題的思路是:掃瞄陣列,記錄當前陣列的和 與 已經記錄的最大的子陣列的和。如果當前記錄的和已經是負數,那麼捨棄它,並重新設定當前陣列和為當前元素的值。否則,比較當前陣列的和與已經記錄的最大的子陣列的和大小,如果比最大的和大,就更新最大和。掃瞄一遍完成統計,滿足題目的要求。
演算法實現如下:
[cpp]view plain
copy
print?
#include
#include
#include
intmaxsubsum(
int*a,
intn)
else
if(cursum > max)
} return
max;
} int
main();
printf("%d \n"
,maxsubsum(a,8));
system("pause"
);
return
0;
}
進一步考慮,如果不僅僅是求最大和,而且要求最大欄位的開始和結束索引。那麼應該怎麼做呢。
演算法的思路還是一樣的,唯一不同的是,我們需要增加兩個變數start和end用來記錄開始和結束的索引。並且在發生變化的時候更新相應的值,那麼掃瞄一遍一樣可以求出最大子段的開始結束索引。
演算法如下
[cpp]view plain
copy
print?
#include
#include
#include
intmaxsubwithindex(
int*a,
intn,
int&start,
int&end)
else
if(cursum > max)
} return
max;
} int
main();
intstart = 0,end = 0;
printf("ok:%d \n"
,maxsubwithindex(a,8,start,end));
printf("starts:%d ends:%d \n"
,start,end);
system("pause"
);
return
0;
}
進一步拓展,對於乙個二維矩陣,一樣存在乙個最大的子矩陣,使得該子矩陣的和為最大。思考一下:這個問題跟之前的最大欄位和的問題有什麼相似之處嗎?
編碼之前,我們不妨先畫個圖:
如果把每一列的和都當做乙個元素的話,那麼問題是不是跟一維的求最大欄位和的問題類似呢?我們只需要順序掃瞄一次矩陣,並求出每個子矩陣的和,然後與最大的和比較,最後可以求出最大子矩陣的和。
演算法對應的**如下:
[cpp]view plain
copy
print?
#include
#include
#define n 3
intmaxsum(
int*a,
intn)
else
if(sum >max)
} return
max;
} int
maxsubmatrix(
int** a,
intm,
intn)
for(j = i;j
sum = maxsum(b,n);
if(sum > max)
} }
return
max;
} main()
} printf("%d\n"
,maxsubmatrix(a,m,n));
for(
inti = 0;idelete
a[i];
delete
a;
} }
求子陣列的最大和 DP
題目 輸入乙個整形陣列,陣列裡有正數也有負數。陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。求所有子陣列的和的最大值。要求時間複雜度為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。因為是o n 的複雜度,...
求子陣列的最大和
題目 輸入乙個整形陣列,陣列裡有正數也有負數。陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。求所有子陣列的和的最大值。要求時間複雜度為o n 本題最初為2005年浙江大學計算機系的考研題的最後一道程式設計題,在2006年裡包括google在內的很多知名公司都把本題當作面試題。由於本...