子數組最大和問題

來源:互聯網
上載者:User

一、問題描述

輸入:一個整型數組,數組裡有正數也有負數。
數組中連續的一個或多個整數組成一個子數組,每個子數組都有一個和。
求所有子數組的和的最大值。要求時間複雜度為O(n)。

例如:

輸入的數組為1, -2, 3, 10, -4, 7, 2, -5

則最大的子數組為3, 10, -4, 7, 2,和為18

 

二、問題分析

1.只要求出最大子數組的起始位置和結束位置,求和則很簡單。不難看出,最大子數組有個特點:起始位置和結束位置的數一定是正數,而且起始位置之前如果還有數,此數一定不是正數,否則我們可以把它也包含進來,這樣和會更大,同理結束位置之後如果有數,那麼也一定不是正數。

2.我們可以先將問題簡化為這樣一個問題:輸入的數組是正負交替的;如果不是,我們可以很輕鬆地將其變成正負交替的:將連續的正數/負數求和成為一個新的正數/負數即可。

如果輸入數組是這樣的:+ - + - + - +,那麼我們可以這樣來解決這個問題:

遍曆這個數組中的數:首先a[0]將是我們最大的子數組;當遍曆到a[1]時不會改變什麼;當遍曆到a[2]時,最大的子數組將可能產生變化:1.保持不變、2.變為a[2]、3.a[0]+a[1]+a[2]。這很簡單,只要比較這三個數哪個最大即可,然後將最大的結果儲存為我們新的最大子數組,繼續遍曆;這時後面的問題基本就是這個步驟的重複,但是有一點需要注意:並不是每當到下一個正數時都會有三種情況,因為我們要保證子數組必須是連續的,所以若a[0]仍然是最大的,則此時它將不能和後續的數串聯起來,因此將只有兩種情形來比較大小。

我們需要建立一個結構體來儲存我們的結果,這個結構體應該包括四個參數:

int start--表示最大子數組的起始座標

int end--表示最大子數組的結束座標

int sum--子數組的和

int flag--標誌此子數組是否可擴充:1代表可擴充,0代表不能擴充(可擴充意味著目前的子數組與即將遍曆到的負數和正數是連續的)

對於我們這個簡化的正負數交替的輸入數組模型,相應的演算法流程可以表示如下:

1.初始化最大子數組為第一個出現的正數:a[0]或a[1],取決於孰正孰負,同時需要置標誌為1--可擴充

2.繼續遍曆數組,當遇到負數時跳過,遇到正數時,則討論:若最大子數組標誌位為1,則比較最大子數組和、當前a[i],以及最大子數組和+當前a[i]+a[i-1],誰最大,則誰是最大子數組;若標誌位為0,則只比較最大子數組和、當前a[i]。同時還需保留新的最大數組,共置標誌位。

#include <stdio.h>typedef struct{int start_pos;//最大子數組起始下標int end_pos;//最大子數組結束下標int sum;//最大子數組和int flag;//標誌位:1--子數組可擴充;0--子數組不可擴充}max_sub_struct;max_sub_struct max_sub;void get_max_sub(int a[], int n){int i;int index;i = initial(a);for ( ; i < n; i ++){if (a[i] < 0){continue;}if (max_sub.flag){index = compare_three_nums(max_sub.sum,a[i],a[i]+a[i-1]+max_sub.sum);if (index == 1){max_sub.flag = 0;}else if (index == 2){max_sub.start_pos = i;max_sub.end_pos = i;max_sub.sum = a[i];max_sub.flag = 1;}else{max_sub.end_pos = i;max_sub.sum = a[i]+a[i-1]+max_sub.sum;max_sub.flag = 1;}}else{if(max_sub.sum < a[i]){max_sub.start_pos = i;max_sub.end_pos = i;max_sub.sum = a[i];max_sub.flag = 1;}else{max_sub.flag = 0;}}}}/**初始化函數,a[0]或a[1]為正,將其儲存到max_sub中,並為遍曆數組的初始位置賦值*/int initial(int a[]){int i;if(a[0] > 0){max_sub.start_pos = 0;max_sub.end_pos = 0;max_sub.sum = a[0];i = 1;}else{max_sub.start_pos = 1;max_sub.end_pos = 1;max_sub.sum = a[1];i = 2;}max_sub.flag = 1;return i;}/**比較三個數,a最大則返回1;b最大則返回2;c最大則返回3*/int compare_three_nums(int a, int b, int c){int max_num  = a;if(max_num < b){max_num = b;}if(max_num < c){max_num = c;}if(max_num == c){return 3;}if(max_num == b){return 2;}if(max_num == a){return 1;}}/**格式化輸出max_sub*/void display_max_sub(void){printf("max_sub.start_pos = %d\n",max_sub.start_pos);printf("max_sub.end_pos = %d\n",max_sub.end_pos);printf("max_sub.sum = %d\n",max_sub.sum);}int main(){int a[] = {-2,13,-4,9,-5};get_max_sub(a,5);display_max_sub();system("pause");return 0;}

未完待續…………

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.