程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C數組中最大和的子數組

C數組中最大和的子數組

編輯:關於C語言

題目:

輸入一個整型數組,數據元素有正數也有負數,求元素組合成 連續子數組之和最大的子數組,要求時間復雜度為O(n)。

例如:

輸入的數組為1, -2, 3, 10, -4, 7, 2, -5,最大和的連續子數組為3, 10, -4, 7, 2,其最大和為18。

背景:

本題最初為2005年浙江大學計算機 系考研題的最後一道程序設計題,在2006年裡包括google在內的很多知名公司都 把本題當作面試題。

由於本題在網絡中廣為流傳,本題也順利成為2006年 程序員面試題中經典中的經典。

分析:

如果不考慮時間復雜度, 我們可以枚舉出所有子數組並求出他們的和。不過非常遺憾的是,由於長度為n的 數組有O(n2)個子數組(即:n + n-1 + ... + 1=n(n+1)/2);而且求一個長度為 n的數組的和的時間復雜度為O(n)。因此這種思路的時間是O(n3)。

很容易 理解,當我們加上一個正數時,和會增加;當我們加上一個負數時,和會減少。 如果當前得到的和是個負數,那麼這個和在接下來的累加中應該拋棄並重新清零 ,不然的話這個負數將會減少接下來的和。基於這樣的思路,我們可以寫出如下 代碼。

void MaxSum(int array[], unsigned int len)     
{     
    if(NULL == array || len <=0){     
        return;     
    }     

    int curSum = 0, maxSum = 0;     
    int i = 0;     
    for(i=0; i<len; i++){     
        curSum += array[i];     // 累加     

        if(curSum < 0){          // 當前和小於0,重置為0     
            curSum = 0;     
        }     

        if(curSum > maxSum){ // 當前和大於最大和,則重置最大和     
            maxSum = curSum;      
        }     
    }     

    if(maxSum == 0){            // 最大和依然為0,說明數組中所有元素都

為負值     
        maxSum = array[0];     
        for(i=1; i<len; i++){     
            if(array[i] > maxSum){     
                maxSum = array[i];     
            }     
        }     
    }     

    printf("maxSum: %d", maxSum);     
}

測試數組:

int array[] = {1, -2, 3, 10, -4, 7, 2, -

5};     // 3, 10, -4, 7, 2 = 18

運行結果:
 

代碼改進:

有時,需要輸出最大和的子數組及其 開始、結束下標,代碼如下:

void MaxSum(int array[], unsigned int len)     
{     
    if(NULL == array || len <=0){     
        return;     
    }     

    int curSum = 0, maxSum = 0;     
    int index_start = 0, index_end = 0;     // 初始化子數組最大和下標   

  
    int i = 0;     
    for(i=0; i<len; i++){     
        curSum += array[i];     // 累加     

        if(curSum < 0){          // 當前和小於0,重置為0     
            curSum = 0;     
            index_start = i+1;      // 調整子數組最大和的開始下標     
        }     

        if(curSum > maxSum){     // 當前和大於最大和,則重置最大和   

  
            maxSum = curSum;      
            index_end = i;          // 調整子數組最大和的結束下標
        }     
    }     

    if(maxSum == 0){            // 最大和依然為0,說明數組中所有元素都

為負值
        maxSum = array[0];     
        index_start = index_end = 0;                // 初始化子數組最大

和下標
        for(i=1; i<len; i++){
            if(array[i] > maxSum){
                maxSum = array[i];     
                index_start = index_end = i;        // 調整子數組最大和

下標
            }
        }
    }

    // 輸出最大和的子數組及其開始、結束下標
    printf("index_start: %d\nindex_end: %d\n", index_start, index_end);
    for(i=index_start; i<=index_end; i++){
        printf("%d\t", array[i]);
    }

    printf("\n\nmaxSum: %d", maxSum);
}

測試數組:

int array[] = {1, -2, 3, 10, -4, 7, 2, -5};     

// 3, 10, -4, 7, 2 = 18

運行結果:

源碼:http://download.csdn.net/detail/sunboy_2050/3961203

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved