- Sliding Window Matrix Maximum
Given an array of n * m matrix, and a moving matrix window (size k * k), move the window from top left to botton right at each iteration, find the maximum sum inside the window at each moving.
Return 0 if the answer does not exist.
Example
For matrix
[
[1, 5, 3],
[3, 2, 1],
[4, 1, 9],
]
The moving window size k = 2.
return 13.
At first the window is at the start of the array like this
[
[|1, 5|, 3],
[|3, 2|, 1],
[4, 1, 9],
]
,get the sum 11;
then the window move one step forward.
[
[1, |5, 3|],
[3, |2, 1|],
[4, 1, 9],
]
,get the sum 11;
then the window move one step forward again.
[
[1, 5, 3],
[|3, 2|, 1],
[|4, 1|, 9],
]
,get the sum 10;
then the window move one step forward again.
[
[1, 5, 3],
[3, |2, 1|],
[4, |1, 9|],
]
,get the sum 13;
SO finally, get the maximum from all the sum which is 13.
Challenge
O(n^2) time.
解法1:
思路:先求accums[],即matrix[][]的每k行的累加和。然后对accums[]每行求其固定size的subarray的最大值,即调用maxFixSizeSubArray()。
注意求固定size的subarray的最大值必须用sliding window或deque,跟前面做过的Continuous Subarray(LintCode 402, 403)不一样,那两题没有固定size大小。
代码如下:
class Solution {
public:
/**
* @param matrix: an integer array of n * m matrix
* @param k: An integer
* @return: the maximum number
*/
int maxSlidingMatrix(vector<vector<int>> &matrix, int k) {
int m = matrix.size();
if (m < k) return 0;
int n = matrix[0].size();
if (n < k) return 0;
vector<vector<int>> accums(m - k + 1, vector<int>(n, 0));
for (int i = 0; i < k; ++i) {
for (int j = 0; j < n; ++j) {
accums[0][j] += matrix[i][j];
}
}
for (int i = 1; i <= m - k; ++i) {
for (int j = 0; j < n; ++j) {
accums[i][j] = accums[i - 1][j] - matrix[i - 1][j] + matrix[i + k - 1][j];
}
}
int maxSum = INT_MIN;
for (int i = 0; i < m - k + 1; ++i) {
maxSum = max(maxSum, maxFixSizeSubArray(accums[i], k));
}
return maxSum;
}
private:
int maxFixSizeSubArray(vector<int> & nums, int k) {
int n = nums.size();
if (n < k) return 0;
int sum = 0, maxSum = 0;
for (int i = 0; i < k; ++i) {
sum += nums[i];
}
maxSum = sum;
for (int i = 1; i < n - k + 1; ++i) {
sum += nums[k + i - 1] - nums[i - 1];
maxSum = max(maxSum, sum);
}
return maxSum;
}
};
解法2:直接用DP。
代码如下:
class Solution {
public:
/**
* @param matrix: an integer array of n * m matrix
* @param k: An integer
* @return: the maximum number
*/
int maxSlidingMatrix(vector<vector<int>> &matrix, int k) {
int m = matrix.size();
if (m < k) return 0;
int n = matrix[0].size();
if (n < k) return 0;
vector<vector<int>> sums(m + 1, vector<int>(n + 1, 0));
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
sums[i][j] = sums[i][j - 1] + sums[i - 1][j] - sums[i - 1][j - 1] + matrix[i - 1][j - 1];
}
}
int result = INT_MIN;
for (int i = k; i <= m; ++i) {
for (int j = k; j <= n; ++j) {
result = max(result, sums[i][j] - sums[i - k][j] - sums[i][j - k] + sums[i - k][j - k]);
}
}
return result;
}
};