求最小子数组之二维篇
一、設計思路
??求出該二維數組的所有子數組,先確定一個位置為起點,然后向右下方依次以此起點為始的所有子數組,
圖1—順序求子數組
具體如上圖1,順序求出子數組,然后和max值相比較,若比max值大,則將該子數組和賦給max,并保存其位置,對該子數組的位置,只需要保存其首尾位置即可,
????????????????????????
???圖2—保存子數組位置
如上圖2所示,得到了最大子數組和與其位置,輸出即可。
二、代碼
1 package zishuzu; 2 3 import java.util.*; 4 5 public class zuixiaozishuzu { 6 7 public static void main(String[] args) { 8 // TODO Auto-generated method stub 9 10 int m,n,M,N,max,sum; 11 int i,i1,i2,j,j1,j2; 12 int shouL,shouR,weiL,weiR; 13 Scanner sc = new Scanner(System.in); 14 System.out.println("輸入二維數組的行數和列數:"); 15 m = sc.nextInt(); 16 n = sc.nextInt(); 17 System.out.println("輸入該二位數組的取值范圍(保證第一個數小于第二個數):"); 18 M = sc.nextInt(); 19 N = sc.nextInt(); 20 21 int[][] Shuzu = new int[m][n]; 22 for(i = 0;i < m;i++) 23 for(j = 0;j < n;j++) 24 { 25 Shuzu[i][j] = N + (int)(Math.random()*(M - N)); 26 } 27 System.out.println("該隨機二維數組為:"); 28 for(i = 0;i < m;i++) 29 for(j = 0;j < n;j++) 30 { 31 System.out.print(Shuzu[i][j]+"\t"); 32 if(j == n - 1) 33 { 34 System.out.print("\n"); 35 } 36 } 37 38 sum =0; 39 max = Shuzu[0][0]; 40 shouL = 0; 41 shouR = 0; 42 weiL = 0; 43 weiR = 0; 44 45 for(i = 0;i < m;i++) 46 { 47 for(j = 0;j < n;j++) 48 { 49 for(i1 = i;i1 < m;i1++) 50 { 51 for(j1 = j;j1 < n;j1++) 52 { 53 for(i2 = i;i2 <= i1;i2++) 54 { 55 for(j2 = j;j2 <= j1;j2++) 56 { 57 sum = sum + Shuzu[i2][j2]; 58 } 59 } 60 if(max <= sum) 61 { 62 max = sum; 63 shouL = i; 64 shouR = j; 65 weiL = i1; 66 weiR = j1; 67 } 68 sum = 0; 69 } 70 } 71 } 72 } 73 74 System.out.println("最大子數組和為:"); 75 System.out.println(max); 76 System.out.println("最大子數組為:"); 77 for(i = shouL;i <= weiL;i++) 78 for(j = shouR;j <= weiR;j++) 79 { 80 System.out.print(Shuzu[i][j] + "\t"); 81 if(j == weiR) 82 { 83 System.out.print("\n"); 84 } 85 } 86 87 sc.close(); 88 } View Code三、實驗結果
圖3—結果1
圖4—結果2
圖5—結果3
四、開發過程
? 一個二維數組,當看到求最小子數組時,立馬蹦出的想法就是求出這個二維數組的每一個子數組,雖然想法普通,時間復雜度高,卻也不用考慮很多的特殊情況,出錯的風險低了許多。
??設計之初就是一個時間復雜度為n6的一個思路,第一層即最外層是關于起始位置的循環,第二層是關于終止位置的循環,最里層則是該子數組的自加求和,每層有兩個for循環。
? 在一開始編寫時,將循環時的值設為i,ii,iii,j,jj,jjj,運行時卻失敗了,花了兩節課怎么也找不到錯誤,突然想起同伴的提醒:為什么不用i,i1,i2,j1,j1,j2,這樣不是更容易看點,于是便將所有值該了過來,改到最后一個jjj值時,才發現,我是將“jjj”寫成了“jj”,導致了程序的無限循環。
??在研究錯誤的兩節課里,經同伴提醒,想要減少時間復雜度,就是修改每層的for循環,減少一個,將i++寫在for循環內,具體代碼如下:
1 i = 0; 2 for(j = 0;j < n;j++) 3 { 4 i1 = i; 5 for(j1 =j;j1 < n;j1++) 6 { 7 i2 = i; 8 for(j2 = j;j2 <= j1;j2++) 9 { 10 sum += Shuzu[i2][j2]; 11 if((j2 == j1)&&(i2 < i1)) 12 { 13 i2++; 14 j2 = j; 15 } 16 else if(j2 == j1&&i2 == i1) 17 { 18 break; 19 } 20 } 21 if(max < sum) 22 { 23 max = sum; 24 shouL = i; 25 shouR = j; 26 weiL = i1; 27 weiR = j1; 28 } 29 sum = 0; 30 if(j1 == n -1 && i1 < m -1) 31 { 32 i1++; 33 j1 = j; 34 } 35 else if(j1 == n-1 && j1 == m - 1) 36 { 37 break; 38 } 39 } 40 if(j == n - 1 && j < m - 1) 41 { 42 i++; 43 j = 0; 44 } 45 else if(j == n - 1 && j == m - 1) 46 { 47 break; 48 } 49 } View Code能運行出來,可檢驗時發現有的運算結果是錯誤的,所以就先用了第一種方法。
??這個程序還可以稍作改進,就是當存在最大子數組和相同的子數組時,將所有數組都輸出,可以用數組來保存。
五、結對開發成員
劉雙渤,劉洪陽
轉載于:https://www.cnblogs.com/little-clever/p/4412637.html
總結
以上是生活随笔為你收集整理的求最小子数组之二维篇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第二篇:白话tornado源码之待请求阶
- 下一篇: 织梦channel标签currentst