題目:要求乙個陣列連續下標和的最大值,陣列的元素可正、可負、可為零,例如-2,5,3,-6,4,-8,6將返回8。
這題是很經典的一道面試題,也有各種解法,從演算法分析上,時間複雜度也有很大差別,下面我就給出三種不同的解法。
方法一:暴力列舉法
此種方法最簡單,我想應該也是每個人拿到題目想到的第一種解法了,學過一點程式設計的人都應該能編出此類程式。
記sum[i..j]為陣列中第i個元素到第j個元素的和(其中0<=imaxium do //更新最大值
maxium = sum;
return maxium;
}此種方法的時間複雜度為o(n2),顯然不是一種很好的辦法,也不是公司面試希望你寫出這樣的程式的。
方法二:分支界定
這裡再介紹一種更高效的演算法,時間複雜度為o(nlogn)。這是個分治的思想,解決複雜問題我們經常使用的一種思維方法——分而治之。
而對於此題,我們把陣列a[1..n]分成兩個相等大小的塊:a[1..n/2]和a[n/2+1..n],最大的子陣列只可能出現在三種情況:
a[1..n]的最大子陣列和a[1..n/2]最大子陣列相同;
a[1..n]的最大子陣列和a[n/2+1..n]最大子陣列相同;
a[1..n]的最大子陣列跨過a[1..n/2]和a[n/2+1..n]
前兩種情況的求法和整體的求法是一樣的,因此遞迴求得。
第三種,我們可以採取的方法也比較簡單,沿著第n/2向左搜尋,直到左邊界,找到最大的和maxleft,以及沿著第n/2+1向右搜尋找到最大和maxright,那麼總的最大和就是maxleft+maxright。
而陣列a的最大子陣列和就是這三種情況中最大的乙個。
偽**如下:
int maxsubarray(int *a,int l,int r)
這種演算法時間複雜度只是o(n),效果非常好!
具體實現**如下:
複製**
#include
#include
#include
#include
#include
using namespace std;
const int inf=0x7fffffff;
int max_sub_array(int arr,int n,int &left,int &right)}}
return maxium;
}int max_sub_array(int arr,int l,int r,int &left,int &right)
}int max_right=-inf;
sum_both=0;
for(int i=mid+1;i<=r;i++)
}sum_both=max_left+max_right;
if(sumlmaxsum)
}return maxsum;
}void test1()
;int len=sizeof(arr)/sizeof(arr[0]);
int left,right;
int sum;
cout<<"arr:";
copy(arr,arr+len,ostream_iterator(cout, " "));
cout<(cout, " "));
cout cout<<"method1:(" cout<<"method2:(" cout<<"method3:(" 複製** 其中test1函式是題目給出的陣列測試,test2是進行隨機產生數來測試。 大致的效果如下: test1測試: test2測試: 參考: from 題目 要求乙個陣列連續下標和的最大值,陣列的元素可正 可負 可為零,例如 2,5,3,6,4,8,6將返回8。這題是很經典的一道面試題,也有各種解法,從演算法分析上,時間複雜度也有很大差別,下面我就給出三種不同的解法。方法一 暴力列舉法 此種方法最簡單,我想應該也是每個人拿到題目想到的第一... 1.宣告乙個陣列,宣告是用常量表示式指定陣列維數,然後可以勇敢數租明訪問數租元素。2.宣告乙個變長數租,宣告是用變數表示式指定陣列維數,然後用陣列名來訪問陣列元素 c99特性 double item n 如果n是乙個變數,c99之前不允許這樣做。3.宣告乙個指標,呼叫malloc 然後使用指標來訪問... 給你10 分鐘時間,根據上排給出十個數,在其下排填出對應的十個數 要求下排每個數都是先前上排那十個數在下排出現的次數。上排的十個數如下 0,1,2,3,4,5,6,7,8,9 舉乙個例子,數值 0,1,2,3,4,5,6,7,8,9 分配 6,2,1,0,0,0,1,0,0,0 0 在下排出現了 6...三種演算法求解乙個陣列的子陣列最大和
建立乙個陣列有三種方法
乙個陣列演算法題,利用遞迴 回溯求解