演算法的設計這個問題太過龐大,對於乙個程式設計師來說,最好的辦法就是多接觸不同的演算法,並且時刻總結。
問題:乙個一維的整數陣列,有n個元素,元素有正數也有負數。找到陣列中任意連續個元素最大和。
方法一:使用暴力法找到所有的子串行,並計算出所有子串行的和,結果自然就得到了。這種方法的事件複雜度是o(n*n)
vectortestarray = ;
int solution1()
} return res;
}
方法二:分治思想。如果把陣列分為左右兩部分,那麼原問題就可以看做,在陣列左半部分中最大子串行和、陣列右半部分中最大子串行和、以及貫穿陣列左右部分的最大序列和中,調選出三者最大的值。而陣列左半部分中最大子串行和可以看做是乙個原問題,如此遞迴就可以得到結果。這種折半遞迴的方法時間複雜度是o(logn),而每次遞迴都需要找到,貫穿陣列左右部分的最大序列和,這部分的時間複雜度是o(n),也就是說這種方法的時間複雜度是o(nlogn)。我本來覺得這種方法很蠢,這種演算法並沒有什麼巧妙地,而且效果也不怎麼好。但是轉念一想,這只是簡單的轉換了一下思維方式,效果就有所提公升,雖然說提公升不是很大,但是我們為這種提公升的付出也是很小的,僅僅轉變了一下思維方式而已。
//計算[start, mid)中,以mid-1為終點的子向量的最大和
for(int i = mid - 1; i >= start; i--)
//計算[mid, end)中, 以mid為起點的子向量的最大和
sum = 0;
for(int i = mid; i < end; i++)
return max();
}方法三:動態規劃。這是一種很典型的演算法,這裡就不展開說明啦。
int solution3()
return maxsofar;
}
引申問題:如果給出乙個二維陣列矩陣,找出子矩陣最大和。
分析:當問題從一維陣列到二維陣列,情況就變得十分複雜。方法是,對二維陣列的列使用暴力的兩層迴圈(上面的方法一),同時對二位陣列的行使用動態規劃(上面的方法三),這種方法的時間複雜度是o(n*m*m),其中n是陣列的行,m是陣列的列。
vector> testmatrix = ,,,
,,};int solution4()
maxendinghere = max(maxendinghere + sumline, 0);
maxsofar = max(maxsofar, maxendinghere);
}} }
return maxsofar;
}
程式設計珠璣第八章 演算法設計技術
本章就乙個小問題研究了四種不同的演算法,重點強調了這些演算法的設計技術,綜合本章內容,告訴我們 複雜深奧的演算法有時可以極大地提高程式效能。問題定義 具有n個浮點數的向量x,求出輸入向量的任何連續子向量的最大和。立方演算法 maxsofar 0 for i 0,n for j i,n sum 0 f...
程式設計珠璣第八章 演算法設計技術
首先思考乙個問題,給定乙個含有n個元素的vector,找出其中最大的子向量 即所有元素之和為最大值 如果是都為正數,那麼問題變得十分簡單,整個vector即是最大子向量,但是如果是正數負數混合的形式呢?問題將變得複雜,接下來將簡要介紹幾種演算法的思路。其複雜度由最初的立方演算法降低到最終的線性演算法...
程式設計珠璣 第八章 演算法設計技術
一,概述 問題 求一維陣列中連續子向量的最大和。例如 a 6 則最大連續子向量的和 為 10 8 18 1 解法一 簡單演算法 include define max a,b a b a b int main int i,j,k int sum 0 int maxsofar 0 for i 0 i 6...