LintCode 558: Sliding Window Matrix Maximum

  1. 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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值