子数组最大累加和
给定一个数组arr,返回子数组的最大累加和
例:arr=[1,-2,3,5,-2,6,-1];所有的子数组中[3,5,-2,6]可以累加出最大的和12,所以返回12static void findByForce(int[] arr){int manSum=arr[0];for(int i=0;i<arr.length;i++){int sum=arr[j];//某个元素为子数组的第一个元素int maxOfJ=sum;for(int i=j;i<arr.length;i++){sum+=arr[i];//累加后续元素if(sum>maxOfJ){maxOfJ=sum;//某个元素后续最大累加}}if(maxOfJ>maxSum){maxSum=maxOfJ;// 总的最大值}}System.out.println(maxSum);
}//递推法 o(n)
static int findByDp(int[] arr){int sumJ=arr[0];///前J个元素的最大贡献int max=sumJ;int left=0;right=0;//***若是求最大值之间的下标int temp;//记录最大值的letffor(int j=1;j<arr.length;j++){if(sumJ>=0){//左子表的最大和为正,继续向后累加sumJ+=arr[j];//若是大于0,则可以要前面的一段}else{//若是小于0,则从当前位置重新开始sumJ=arr[j];// left=j;//重新开始时,更新left//**上面那行是错的,他最终只会停在最后一次sumJ小于0的位置temp=j;}if(sumJ>max){//最大值left=temp;//*如此,只有最大值得到更新,才能更新letfmax=sumJ;// 每次求得最大值,更新最大值时,同时更新rightright=j;}}return max;}
子矩阵最大累加和
给定一个矩阵matrix,其中的值有正、有负、有0、返回子矩阵的最大累加和
例如,matrix为:
-1 -1 -1
-1 2 2
-1 -1 -1
其中最大累加和的子矩阵为
2 2
所以返回4从第一行开始,作为起始行,先求第一行,找最大子数组和,再将下一行于上一行累加到一起,找最大子数组和然后变更起始行,继续之前的循环private static int maxSum(int[][] matrix){int beginRow=0;final int M=matrix.length;final int N=matrix[0].length;int[] sums=new int[N];//按列求和int max=0;//历史最大的子矩阵和while(beginRow<M){//起始行for(int i=beginRow;i<M;i++){//从起始行到最后一行//按列累加for(int j=0;j<N;j++){sums[j]+=matrix[i][j];}//累加完成int t=findByDp(sums);//求出sums的最大和子数组if(t>max)max=t;}//另起一行作为起始行,把sums清零Arrays.fill(sums,0);//将sums的每个元素都设定为0beginRoww++;//以下一行作为起始行}return max;}public static int findByDp(int[] arr){if(arr.length==0)return 0;int sumJ=arr[0];///前J个元素的最大贡献int max=sumJ;int left=0;right=0;//***若是求最大值之间的下标int temp;//记录最大值的letffor(int j=1;j<arr.length;j++){if(sumJ>=0){//左子表的最大和为正,继续向后累加sumJ+=arr[j];//若是大于0,则可以要前面的一段}else{//若是小于0,则从当前位置重新开始sumJ=arr[j];// left=j;//重新开始时,更新left//**上面那行是错的,他最终只会停在最后一次sumJ小于0的位置temp=j;}if(sumJ>max){//最大值left=temp;//*如此,只有最大值得到更新,才能更新letfmax=sumJ;// 每次求得最大值,更新最大值时,同时更新rightright=j;}}return max;}