トピック:インタビューの質問17.24。最大サブマトリックス
正と負の整数で構成されるN×M行列が与えられた場合、要素の合計が最大の部分行列を見つけるコードを記述します。
配列[r1、c1、r2、c2]を返します。r1、c1はサブマトリックスの左上隅の行番号と列番号を表し、r2、c2は右下隅の行番号と列番号をそれぞれ表します。条件を満たすサブマトリックスが複数ある場合は、いずれか1つを返すことができます。
注:この質問は、本の元の質問から少し変更されています
例:
输入:
[
[-1,0],
[0,-1]
]
输出: [0,1,0,1]
解释: 输入中标粗的元素即为输出所表示的矩阵
説明:
- 1 <= matrix.length、matrix [0] .length <= 200
ソース:LeetCode(LeetCode)
リンク:https ://leetcode-cn.com/problems/max-submatrix-lcci
著作権はLeetCode が所有しています。商用転載については、正式な許可書にご連絡ください。非商用転載については、出典を明記してください。
基本的な考え方:動的プログラミング
この質問は、最大のサブセグメント合計の拡張であり、1つの次元を2つの次元に変換します。
ソリューションのアイデア:2次元の次元を1次元に減らし、最大のサブセグメントの合計のアイデアを使用して解決します
- 行列を圧縮します。つまり、各列のプレフィックスの合計(最初のi要素の合計)を見つけます。
- 任意の2つの行の中で最大のサブマトリックス合計を見つけます(最大のサブセグメント合計の考え方)
- 最大のサブマトリックスの左上隅と右下隅の位置がここで決定されるため、解法プロセスの2番目のステップでサブマトリックスの開始列が記録されます
注:Xiaoxuはこの質問について述べましたBステーションは非常に明確です、参照リンク:ビデオリンク
class Solution {
public:
vector<int> getMaxMatrix(vector<vector<int>>& matrix) {
int row = matrix.size(), col = matrix[0].size();
int part_sum[col][row + 1];
//求每一列的前缀和
for(int i = 0; i < col; ++i){
part_sum[i][0] = 0;
for(int j = 0; j < row; ++j){
part_sum[i][j + 1] = part_sum[i][j] + matrix[j][i];
}
}
int res = INT_MIN;
vector<int> result(4);
//求任意两行之间的最大子矩阵和
for(int i = 0; i < row; ++i){
for(int j = i; j < row; ++j){
int s_col = 0;//起始列为0
int dp = 0;
for(int k = 0; k < col; ++k){
//终止列
if(dp > 0){
dp += part_sum[k][j + 1] - part_sum[k][i];
}
else{
s_col = k;
dp = part_sum[k][j + 1] - part_sum[k][i];
}
if(dp > res){
res = dp;
result = {
i, s_col, j, k};
}
}
}
}
return result;
}
};
/*
这道题是最大子段和的延伸,
基本思路:将这道题转化为最大子段和
1.将二维数组压缩成一维数组,就可以用最大子段和的动态规划思路;压缩方法:求每一列的前i个元素的和
2.然后求任意[i,j]行所构成的最大子矩阵
*/