求最小子数组之二维篇
一、設(shè)計(jì)思路
??求出該二維數(shù)組的所有子數(shù)組,先確定一個(gè)位置為起點(diǎn),然后向右下方依次以此起點(diǎn)為始的所有子數(shù)組,
圖1—順序求子數(shù)組
具體如上圖1,順序求出子數(shù)組,然后和max值相比較,若比max值大,則將該子數(shù)組和賦給max,并保存其位置,對(duì)該子數(shù)組的位置,只需要保存其首尾位置即可,
????????????????????????
???圖2—保存子數(shù)組位置
如上圖2所示,得到了最大子數(shù)組和與其位置,輸出即可。
二、代碼
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("輸入二維數(shù)組的行數(shù)和列數(shù):"); 15 m = sc.nextInt(); 16 n = sc.nextInt(); 17 System.out.println("輸入該二位數(shù)組的取值范圍(保證第一個(gè)數(shù)小于第二個(gè)數(shù)):"); 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("該隨機(jī)二維數(shù)組為:"); 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("最大子數(shù)組和為:"); 75 System.out.println(max); 76 System.out.println("最大子數(shù)組為:"); 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三、實(shí)驗(yàn)結(jié)果
圖3—結(jié)果1
圖4—結(jié)果2
圖5—結(jié)果3
四、開發(fā)過程
? 一個(gè)二維數(shù)組,當(dāng)看到求最小子數(shù)組時(shí),立馬蹦出的想法就是求出這個(gè)二維數(shù)組的每一個(gè)子數(shù)組,雖然想法普通,時(shí)間復(fù)雜度高,卻也不用考慮很多的特殊情況,出錯(cuò)的風(fēng)險(xiǎn)低了許多。
??設(shè)計(jì)之初就是一個(gè)時(shí)間復(fù)雜度為n6的一個(gè)思路,第一層即最外層是關(guān)于起始位置的循環(huán),第二層是關(guān)于終止位置的循環(huán),最里層則是該子數(shù)組的自加求和,每層有兩個(gè)for循環(huán)。
? 在一開始編寫時(shí),將循環(huán)時(shí)的值設(shè)為i,ii,iii,j,jj,jjj,運(yùn)行時(shí)卻失敗了,花了兩節(jié)課怎么也找不到錯(cuò)誤,突然想起同伴的提醒:為什么不用i,i1,i2,j1,j1,j2,這樣不是更容易看點(diǎn),于是便將所有值該了過來,改到最后一個(gè)jjj值時(shí),才發(fā)現(xiàn),我是將“jjj”寫成了“jj”,導(dǎo)致了程序的無限循環(huán)。
??在研究錯(cuò)誤的兩節(jié)課里,經(jīng)同伴提醒,想要減少時(shí)間復(fù)雜度,就是修改每層的for循環(huán),減少一個(gè),將i++寫在for循環(huán)內(nèi),具體代碼如下:
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能運(yùn)行出來,可檢驗(yàn)時(shí)發(fā)現(xiàn)有的運(yùn)算結(jié)果是錯(cuò)誤的,所以就先用了第一種方法。
??這個(gè)程序還可以稍作改進(jìn),就是當(dāng)存在最大子數(shù)組和相同的子數(shù)組時(shí),將所有數(shù)組都輸出,可以用數(shù)組來保存。
五、結(jié)對(duì)開發(fā)成員
劉雙渤,劉洪陽
轉(zhuǎn)載于:https://www.cnblogs.com/little-clever/p/4412637.html
總結(jié)
以上是生活随笔為你收集整理的求最小子数组之二维篇的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第二篇:白话tornado源码之待请求阶
- 下一篇: 织梦channel标签currentst