動態規劃——連續子序列最大和
阿新 • • 發佈:2019-02-06
題目描述:
輸入一個整型陣列,數組裡有正數也有負數。
陣列中連續的一個或多個整陣列成一個子陣列,每個子陣列都有一個和。
求所有子陣列的和的最大值。要求時間複雜度為O(n)。
例如輸入的陣列為1, -2, 3, 10, -4, 7, 2, -5,和最大的子陣列為3, 10, -4, 7, 2,
因此輸出為該子陣列的和18。
子問題為以當前元素結尾的序列最大和
//遞迴方法:任何遞推公式都能轉化為遞迴. public int maxSum(int []data,int n) { if(n==0) return data[0]; if(maxSum(data,n-1)<=0) return data[n]; else return maxSum(data,n-1)+data[n]; }
//自頂向下記憶化方法 //用一個數組存放計算的值; public int []b=new int[]{-100,-100,-100,-100,-100,-100,-100,-100,-100,-100}; public int maxSum1(int []data,int n) { if(n==0) { b[0]= data[0]; return b[0]; } if(b[n-1]==-100)//用陣列記憶化的方法!!!!!! { b[n-1]=maxSum(data,n-1); } if(b[n-1]<=0) { b[n]=data[n]; } else { b[n]=b[n-1]+data[n]; } return b[n]; }
//DP_自底向上的方法;index存放最大和子序列的首末下標。 public void maxSum_DP(int []data,int n,int []index) { int start=0; int end=0; int temp=0; int maxsum=0; int []b=new int [data.length]; b[0]=data[0];//第一個為他自己,因前邊沒有數,不能放入遞推公式中; for(int i=0;i<n-1;i++) { if(b[i]<=0) { b[i+1]=data[i+1]; //只有此時才更新temp temp=i+1; } else b[i+1]=b[i]+data[i+1]; //更新座標; if(b[i+1]>maxsum) { maxsum=b[i+1]; start=temp; end=i+1; } } index[0]=start; index[1]=end; }