題目:
Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix such that its sum is no larger than k.
Example:
Input: matrix = [[1,0,1],[0,-2,3]], k = 2
Output: 2
Explanation: Because the sum of rectangle [[0, 1], [-2, 3]]
is 2,
and 2 is the max number no larger than k (k = 2).
Note:
- The rectangle inside the matrix must have an area > 0.
- What if the number of rows is much larger than the number of columns?
代碼:
方法一——暴力搜索法:
class Solution {
public:
int maxSumSubmatrix(vector<vector<int>>& matrix, int k) {
if (matrix.empty() || matrix[0].empty()) return 0;
int m = matrix.size(), n = matrix[0].size(), res = INT_MIN;
int sum[m][n];
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
int t = matrix[i][j];
if (i > 0) t += sum[i - 1][j];
if (j > 0) t += sum[i][j - 1];
if (i > 0 && j > 0) t -= sum[i - 1][j - 1];
sum[i][j] = t;
for (int r = 0; r <= i; ++r) {
for (int c = 0; c <= j; ++c) {
int d = sum[i][j];
if (r > 0) d -= sum[r - 1][j];
if (c > 0) d -= sum[i][c - 1];
if (r > 0 && c > 0) d += sum[r - 1][c - 1];
if (d <= k) res = max(res, d);
}
}
}
}
return res;
}
};
會超時
方法二——基於求二維數組最大子矩陣和的算法
class Solution {
public:
int maxSumSubmatrix(vector<vector<int>>& matrix, int k) {
if (matrix.empty() || matrix[0].empty()) return 0;
int m = matrix.size(), n = matrix[0].size(), res = INT_MIN;
for (int i = 0; i < n; ++i) {
vector<int> sum(m);
for (int j = i; j < n; ++j) {
for (int k = 0; k < m; ++k) {
sum[k] += matrix[k][j];
}
int curSum = 0;
set<int> st{{0}};
for (auto a : sum) {
curSum += a;
auto it = st.lower_bound(curSum - k);
if (it != st.end()) res = max(res, curSum - *it);
st.insert(curSum);
}
}
}
return res;
}
};
思路:
矩陣有n列,就有n個起始列,遍歷n個起始列;對於每次第i列作爲起始列,建立一個大小爲m的sum數組,然後對i到n列進行遍歷,每次遍歷得到一個sum數組(sum[k] += matrix[k][j]),這個數組是一維的,求這個一維數組的最大字段和,代表着求相應矩形的最大矩陣元素和。