1. 程式人生 > >Java實驗——輸出二維數組連續二維子數組的最大和

Java實驗——輸出二維數組連續二維子數組的最大和

http ring list static main 整理 右下角 只需要 image

該算法思路,根據我博客裏面一維子數組求和的思路,可以用一個新的二維數組對該二維區域的數組進行求和,例如新的二維數組的第5個位置,就代表從1到5斜對角線的塊狀區域的和,即1,2,4,5這4個數的和,x個位置表示從1到x的斜對角塊狀區域的和,利用循環一一求出對應的和,一次循環即可,這個循環復雜度為O(nm)

技術分享圖片

接著再求出來新的二維數組中,每一個從1到X的塊狀區域的和均被求出,所以對於任意區域X(如圖以具體的例子展示出來),只需要求出其最大值即可。

確定一個點需要兩層循環,即循環O(mn),在二維數組中需要求兩個點,所以復雜度為O(m2n2)。

求值分3種(或者說4種),第1種情況即從1到X區域有最大值,這種情況在上面求和的過程中已經求出最大,所以再進行考慮。

除了不再考慮的情況,第1種最常見的情況是:

對於任意區域X要求和,只需要獲得新的數組X區域右下角的值(第9個數據的值),減去Z區域的右下角的值(第7個數據),減去Y區域右下角的值(第3個數據),加上Z交Y右下角的值即可(第1個數據)。

第2種情況是塊狀區域包含第一行的時候有最大值,只需要求出獲得X區域右下角的值減去Z區域右下角的值最大就行了

第3種情況是塊狀區域包含第一列的時候有最大值,只需要求出獲得X區域右下角的值減去Y區域右下角的值最大就行了

根據上述的條件,實現了以下的算法如下:

package lianxu1;


import java.io.IOException;
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class ShowSub { public static void main(String[] args) throws IOException { Integer c[][]= { {1,2,-3,-1,2,2}, {-3,4,5,1,-1,3}, {-2,-3,4,1,4,3} };
//求和 List<List<Integer>> main=new ArrayList<List<Integer>>(); for(int i=0;i<c.length;i++) { List<Integer> heng=new ArrayList<Integer>(); for(int j=0;j<c[0].length;j++) { if(j!=0) heng.add(c[i][j]+heng.get(j-1)); else heng.add(c[i][j]); } if(i!=0) main.add(addList(heng,main.get(i-1))); else main.add(heng); } //求最大值 int max=main.get(0).get(0); for(int z=0;z<main.size();z++) { int temp=Collections.max(main.get(z)); if(max<temp) { max=temp; } } //確定一位置 for(int i1=0;i1<main.size();i1++) { for(int j1=0;j1<main.get(0).size();j1++) { //確定二位置 for(int i2=i1+1;i2<main.size();i2++) { for(int j2=j1+1;j2<main.get(0).size();j2++) { int g_max=0; if(i1!=0&&j1!=0) { g_max=(main.get(i2).get(j2)+main.get(i1-1).get(j1-1)-main.get(i2).get(j1-1)-main.get(i1-1).get(j2)); } else if(i1!=0) { g_max=(main.get(i2).get(j2)-main.get(i1-1).get(j2)); } else if(j1!=0) { g_max=(main.get(i2).get(j2)-main.get(i2).get(j1-1)); } if(max<g_max) { max=g_max; } } } } } System.out.println("該二維數組整理區域和為:"+main); System.out.println("該二維數組最大塊區域和為:"+max); } public static List<Integer> addList(List<Integer> a,List<Integer> b) { List<Integer> sum=new ArrayList<Integer>(); for(int i=0;i<a.size();i++) { sum.add(a.get(i)+b.get(i)); } // for(int i1=0;i1<a.size();i1++) // { // sum.set(i1,sum.get(i1)+b.get(i1)); // } return sum; } }

根據這個二維數組:

技術分享圖片

結果如下所示:

技術分享圖片

Java實驗——輸出二維數組連續二維子數組的最大和