设计思路:
首先定义产生二维数组,定义可输入二维数组行和列,各位数随机产生;
然后进行最大子数组的求和比较,从每行的第一个数为子数组的起点开始进行不同的子数组遍历比较,只存放最大的子数组,以及记录最大子数组的位置,从第一个数开始每行每列进行求和比较,以求得最大子数组的值,以及最大子数组所包含的数;
最后进行结果的输出与验证。
代码:
法一:
package zishuzu; import java.util.*; public class zuixiaozishuzu { public static void main(String[] args) { // TODO Auto-generated method stub int m,n,M,N,max,sum; int i,i1,i2,j,j1,j2; int shouL,shouR,weiL,weiR; Scanner sc = new Scanner(System.in); System.out.println("输入二维数组的行数和列数:"); m = sc.nextInt(); n = sc.nextInt(); System.out.println("输入该二位数组的取值范围(保证第一个数小于第二个数):"); M = sc.nextInt(); N = sc.nextInt(); int[][] Shuzu = new int[m][n]; for(i = 0;i < m;i++) for(j = 0;j < n;j++) { Shuzu[i][j] = N + (int)(Math.random()*(M - N)); } System.out.println("该随机二维数组为:"); for(i = 0;i < m;i++) for(j = 0;j < n;j++) { System.out.print(Shuzu[i][j]+" "); if(j == n - 1) { System.out.print(" "); } } sum =0; max = Shuzu[0][0]; shouL = 0; shouR = 0; weiL = 0; weiR = 0; for(i = 0;i < m;i++) { for(j = 0;j < n;j++) { for(i1 = i;i1 < m;i1++) { for(j1 = j;j1 < n;j1++) { for(i2 = i;i2 <= i1;i2++) { for(j2 = j;j2 <= j1;j2++) { sum = sum + Shuzu[i2][j2]; } } if(max <= sum) { max = sum; shouL = i; shouR = j; weiL = i1; weiR = j1; } sum = 0; } } } } System.out.println("最大子数组和为:"); System.out.println(max); System.out.println("最大子数组为:"); for(i = shouL;i <= weiL;i++) for(j = shouR;j <= weiR;j++) { System.out.print(Shuzu[i][j] + " "); if(j == weiR) { System.out.print(" "); } } sc.close(); } }法二: package zishuzu; import java.util.*; public class zuixiaozishuzu { public static void main(String[] args) { // TODO Auto-generated method stub int m,n,M,N,max,sum; int i,i1,i2,j,j1,j2; int shouL,shouR,weiL,weiR; Scanner sc = new Scanner(System.in); System.out.println("输入二维数组的行数和列数:"); m = sc.nextInt(); n = sc.nextInt(); System.out.println("输入该二位数组的取值范围(保证第一个数小于第二个数):"); M = sc.nextInt(); N = sc.nextInt(); int[][] Shuzu = new int[m][n]; for(i = 0;i < m;i++) for(j = 0;j < n;j++) { Shuzu[i][j] = N + (int)(Math.random()*(M - N)); } System.out.println("该随机二维数组为:"); for(i = 0;i < m;i++) for(j = 0;j < n;j++) { System.out.print(Shuzu[i][j]+" "); if(j == n - 1) { System.out.print(" "); } } sum =0; max = Shuzu[0][0]; shouL = 0; shouR = 0; weiL = 0; weiR = 0; i = 0; for(j = 0;j < n;j++) { i1 = i; for(j1 =j;j1 < n;j1++) { i2 = i; for(j2 = j;j2 <= j1;j2++) { sum += Shuzu[i2][j2]; if((j2 == j1)&&(i2 < i1)) { i2++; j2 = j; } else if(j2 == j1&&i2 == i1) { break; } } if(max < sum) { max = sum; shouL = i; shouR = j; weiL = i1; weiR = j1; } sum = 0; if(j1 == n -1 && i1 < m -1) { i1++; j1 = j; } else if(j1 == n-1 && j1 == m - 1) { break; } } if(j == n - 1 && j < m - 1) { i++; j = 0; } else if(j == n - 1 && j == m - 1) { break; } } System.out.println("最大子数组和为:"); System.out.println(max); System.out.println("最大子数组为:"); for(i = shouL;i <= weiL;i++) for(j = shouR;j <= weiR;j++) { System.out.print(Shuzu[i][j] + " "); if(j == weiR) { System.out.print(" "); } } sc.close(); } }
结果截图:
结果分析:
首先在结组情况下讨论问题较为快速,很快就想出了解决的办法,两个脑袋的确比一个脑袋强;
在解决时间复杂度问题上,第一个方法明显时间复杂度较高,第二种方法采用减少for循环的方法相对来说降低了一些时间复杂度;
在求最大子数组的过程中,因为for循环比较多的原因,致使很难倒清楚关系,在此也废了不少时间,最终在共同努力下解决了此问题。