最大子矩陣和


參考來源:

https://blog.csdn.net/fengyingjie2/article/details/54427146

https://blog.csdn.net/kavu1/article/details/50547401

 

題目:

給定一個矩陣,都是整數,其中(n≤500),求出其中的最大子矩陣

解題思路:

O(n^2*n^2*n^2)的做法:

很容易想到,可以枚舉一個矩陣的左上角和右下角的坐標確定這個矩陣,然后,再用兩個循環進行統計

O(n^2*n^2)的做法:

對於上面的方法,提前處理一個前綴和,即可省去后面統計的時間復雜度。

正解,即O(n³)事實上並沒有這么多

想要做對這道題,我們先要明白一個最大子段和算法的做法:

例如數字a={8,-2,3,-11,5},我們需要求出一段連續數字的最大和是什么

我們的思想是DP

設f[i]表示從1~i這些位置中的最大子段和

如何轉移?對於當前的點i,我們只有兩種狀態,選擇與上一個子段和連接或者自己重新構成一個子段和。

若選,則與1~i-1的最大子段和有關系,即1~i-1的最長子段和加上當前的a[i],重新構成一個子段和

若不選,則與1~i-1最大子段和沒有關系,自己重新構成了一個子段和

兩者取較大者,即可解決

列出狀態轉移方程:f[i]:=max(a[i],f[i-1]+a[i])

時間復雜度 O(n)


 

 

說了這么多都是鋪墊,下面是重點:

為了能夠在原始矩陣里很快得到從 i 行到 j 行 的上下值之和,我們這里用到了一個輔助矩陣,它是原始矩陣從上到下加下來的。
假設原始矩陣是matrix, 它每一層上下相加后得到的矩陣是total,那么我們可以通過如下代碼實現:

int[][] total = matrix;    
for (int i = 1; i < matrix[0].length; i++) {    
    for (int j = 0; j < matrix.length; j++) {    
    total[i][j] += total[i-1][j];    
    }    
}    

如果我們要求第 i 行到第 j 行之間上下值的和,我們可以通過total[j][k] - total[i-1][k] 得到, k 的范圍從1 到 matrix[0].length - 1。
有了這些知識點,我們只需要在所有的情況下,把它們所對應的局部最大子矩陣進行比較,就可以得到全局最大的子矩陣。代碼如下:

 1 public int subMaxMatrix(int[][] matrix) {    
 2             
 3         int[][] total = matrix;    
 4         for (int i = 1; i < matrix[0].length; i++) {    
 5             for (int j = 0; j < matrix.length; j++) {    
 6                 total[i][j] += total[i-1][j];    
 7             }    
 8         }    
 9             
10         int maximum = Integer.MIN_VALUE;    
11         for (int i = 0; i < matrix.length; i++) {    
12             for (int j = i; j < matrix.length; j++) {    
13                 //result 保存的是從 i 行 到第 j 行 所對應的矩陣上下值的和    
14                                 int[] result = new int[matrix[0].length];    
15                 for (int f = 0; f < matrix[0].length; f++) {    
16                     if (i == 0) {    
17                         result[f] = total[j][f];    
18                     } else {    
19                         result[f] = total[j][f] - total[i - 1][f];    
20                     }    
21                 }    
22                 int maximal = maxSubsequence(result);    
23                     
24                 if (maximal > maximum) {    
25                     maximum = maximal;    
26                 }    
27             }    
28         }    
29             
30         return maximum;    
31     }   

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM