求數組最大子序列問題

目錄

 

最大子序列的概念

具體求解算法   

暴力算法

 優化後的暴力算法

 在線處理

分而治之

運行結果


  • 最大子序列的概念

計算機科學中,最大子數列問題的目標是在數列的一維方向找到一個連續的子數列,使該子數列的和最大。例如,對一個數列 −2, 1, −3, 4, −1, 2, 1, −5, 4,其連續子數列中和最大的是 4, −1, 2, 1, 其和爲6。

  • 具體求解算法   

  • 暴力算法

    ​
    int max_sub_seq1(int *arr, int len) //初始版本 時間複雜度爲O(n^3)
    {
        int   cur_num;
        int   max_num;
        if (!arr || len < 0)
        {
            printf("Error input arguements\n");
            return -1;
        }
        int i, j ,k;
        for (i = 0; i < len; ++i)
        {
            for (j = i; j < len; j++)
            {
                cur_num = 0;
                for (k = i; k <= j; ++k)
                    cur_num += arr[k];
                if(cur_num > max_num)
                {
                    max_num = cur_num;
    
                }
            }
    
        }
        return max_num;
    }
    
    ​

     

  •  優化後的暴力算法

    int max_sub_seq2(int *arr, int len)  //稍加優化 時間複雜度爲O(n^2)
    {
        int   cur_num = 0;
        int   max_num = 0;
        int i, j;
        if (!arr || len < 0)
        {
            printf("Error input arguements\n");
            return -1;
        }
        for (i = 0; i < len; i++)
        {
            cur_num = 0;
            for (j = i; j < len; j++)
            {
                cur_num += arr[j];
                if(cur_num > max_num)
                    max_num = cur_num;
            }
    
        }
        return max_num;
    }

     

  •  在線處理

    /*在線處理的思想來優化代碼 時間複雜度爲n,但是對於數據元素全爲負數的序列求值爲(0)會出錯*/
    
    int max_sub_seq3(int *arr, int len)  
    {
        int i, j;
        int   cur_num;
        int   max_num;
        if (!arr || len < 0)
        {
            printf("Error input arguements\n");
            return -1;
        }
        cur_num = max_num = 0;
        for (i = 0; i < len; i++)
        {
            cur_num += arr[i];
            if(cur_num > max_num)
                max_num = cur_num;
            else if(cur_num < 0)
            {
                cur_num = 0;
            }
    
        }
        return max_num;
    }

    備註:種方式只能用於一個數據元素非全負的數組序列,若數組序列爲全負,則其子序列求和爲

  • 分而治之

    inline int max_three_num(int num1, int num2, int num3)  //求得三數的最大值
    {
    
        int max = 0;
        max = num1 > num2 ? num1:num2;
        max = num3 > max ?  num3:max;
        return max;
    }
    
    int maxcross(int *arr, int left, int mid, int right) //求出有交叉的左右序列的和
    {  
        int i;
        int sum = 0;
        int leftSum = 0;
        int rightSum = 0;
        for (i = mid; i >=left; i--)
        {
            sum += arr[i];
            if (sum > leftSum)
                leftSum = sum;
        }
        sum = 0;
        for (i = mid + 1; i <= right; i++)
        {
            sum += arr[i];
            if (sum > rightSum)
                rightSum = sum;
        }
        return leftSum + rightSum;
    }
    
    int DivideandRule(int *arr, int left,int right) /* 分而治之*/
    {
        int mid=0;
        int maxLeft=0, maxRight=0, maxMiddle=0;
        if (left == right)
        {
            if (arr[left] > 0)
                return arr[left];
            else
                return 0;
        }
    
        mid = (left + right) / 2;
    
        maxLeft = DivideandRule(arr, left, mid);         /*左序列遞歸求和*/
    
        maxRight = DivideandRule(arr, mid + 1, right);   /*右序列遞歸求和0*/
        maxMiddle = maxcross(arr,left,mid,right);        /* 有交集的左右序列求和 */
        return max_three_num(maxLeft, maxRight, maxMiddle);
    }
    

     

  • 運行結果

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章