一個簡單算法的設計(一個數組中連續區間和的最大值)


   今天做了一個程序,是實現結對編程的小項目,項目是尋找一組數組中最大的一組子數組(條件是數組必須連續)。通過我們模擬一組數據:

   例如:int a[]={9,8,-5,4,3}

  首先是選定一個初始值假如是a[0],則第二個數是a[0]+a[1]........可以這樣理解:

     即第一層從a[0]開始     設置一個初始最大值:max

     Sum1=a[0];                //   max=sum1      

     Sum2=a[0]+a[1];           //sum2=sum1+a[1];  if(sum2>max)  max=sum2;

     Sum3=a[0]+a[1]+a[2]....     //sum3=sum2+a[2];  if(sum3>max)  max=sum3;

     第二層從a[1]開始

     Sum4=a[1];               //if(sum4>max)  max=sum4;        

     Sum5=a[1]+a[2];           //sum5=sum4+a[2];  if(sum5>max)  max=sum5

      Sum6=a[1]+a[2]+a[3].......    //sum6=sum5+a[3];  if(sum6>max)  max=sum6

      ....................

    然后通過每一層進行比較,得出一層的Max,與下層繼續比較,直到找到最大相鄰的子數組的和。

   算法模擬:

   假設數組為a[];

  For i=(0 to n)

      Sum=0;

     For j=(i to n);

        Sum=sum+a[j];

       If(sum>max)

            Max=sum;

       具體實現代碼:

package com.su.test;
public class Hellosu {
    public static void main(String[] args)
    {
      int a[]={-1,-2,5,-3};    //測試用例
      int length=a.length;
      int max=a[0];
      for(int i=0;i<length;i++)
      {
          int sum=0;               //每次賦值一層的第一個數
          for(int j=i;j<length;j++)
          {
              sum=sum+a[j];             //為后面連續數相加
              if(sum>max)
              {
                  max=sum;              //最大則存儲在Max中
              }
          }
      }
      System.out.println(max);  
    }
 }
View Code 

 測試用例:

          int a[]={9,-3,4,-5,0};   測試結果:

          int a[]={-4,-5,-10,7,4,-12,19,0,-4,-6};  測試結果:

   算法分析:

         第一個循環內部的語句需要執行N次,而每次執行外部循環時,第二個循環內的語句至多執行N次,所以總的運行時間為O(n*n),而並沒有達到老師所要求的水平,即O(n),

   可以考慮到如果檢測所有的那些值的話,算法至少花費二次方的的時間。所以引出來是否可以有一個更好的方法能更有效地得出結果?

       第二種方法:即利用動態規划解決問題

   令cur(i)表示數組下標以i為起點的最大連 續下標最大的和,而max(i)表示前i個元素的最大子數組之和。那么我們就可以推出下一個max(i+1)應該為cur(i+1)和max(i)中選取一個最大值。遞推式為:
          cur(i) = max{A[i],cur(i-1)+A[i]};
          max(i) = max{max(i-1),cur(i+1)};

     偽代碼:

int max(int a[],int n) { 
    cur = a[0]; 
    max = a[0];
    for i=1 to n-1 do
        if cur<0 do 
            cur = 0;
        cur += a[i]; 
        if cur>max do
            max = cur; 
    return max; 
}

   源代碼:

package com.su.test;

public class Second {
   public static void main(String args[])
   {
       int a[]={-1,-2,4,3,-2};    //測試用例
       int length=a.length;
       int cur=a[0];
       int max=a[0];
       for(int i=0;i<length;i++)
       {
           if(cur<0)
                cur=0;
           cur+=a[i];
           if(cur>max)
                max=cur;
       }
      System.out.println(max);
   }
}
View Code

這種算法很好充分利用了動態規划解決問題。而且算法的時間復雜度為O(n).

         

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM