[LeetCode] Max Sum of Rectangle No Larger Than K 最大矩阵和不超过K

简介:

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:

Given matrix = [
  [1,  0, 1],
  [0, -2, 3]
]
k = 2

 

The answer is 2. Because the sum of rectangle [[0, 1], [-2, 3]] is 2 and 2 is the max number no larger than k (k = 2).

Note:

  1. The rectangle inside the matrix must have an area > 0.
  2. What if the number of rows is much larger than the number of columns?

Credits:

Special thanks to @fujiaozhu for adding this problem and creating all test cases.

这道题给了我们一个二维数组,让我们求和不超过的K的最大子矩形,那么我们首先可以考虑使用brute force来解,就是遍历所有的子矩形,然后计算其和跟K比较,找出不超过K的最大值即可。就算是暴力搜索,我们也可以使用优化的算法,比如建立累加和,参见之前那道题Range Sum Query 2D - Immutable,我们可以快速求出任何一个区间和,那么下面的方法就是这样的,当遍历到(i, j)时,我们计算sum(i, j),表示矩形(0, 0)到(i, j)的和,然后我们遍历这个矩形中所有的子矩形,计算其和跟K相比,这样既可遍历到原矩形的所有子矩形,参见代码如下:

解法一:

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;
    }
};

下面这个算法进一步的优化了运行时间,这个算法是基于计算二维数组中最大子矩阵和的算法,可以参见youtube上的这个视频Maximum Sum Rectangular Submatrix in Matrix dynamic programming/2D kadane。这个算法巧妙在把二维数组按行或列拆成多个一维数组,然后利用一维数组的累加和来找符合要求的数字,这里用了lower_bound来加快我们的搜索速度,也可以使用二分搜索法来替代。我们建立一个集合set,然后开始先放个0进去,为啥要放0呢,因为我们要找lower_bound(curSum - k),当curSum和k相等时,0就可以被返回了,这样我们就能更新结果了。由于我们对于一维数组建立了累积和,那么sum[i,j] = sum[i] - sum[j],其中sums[i,j]就是目标子数组需要其和小于等于k,然后sums[j]是curSum,而sum[i]就是我们要找值,当我们使用二分搜索法找sum[i]时,sum[i]的和需要>=sum[j] - k,所以也可以使用lower_bound来找,参见代码如下:

解法二:

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, 0);
            for (int j = i; j < n; ++j) {
                for (int k = 0; k < m; ++k) {
                    sum[k] += matrix[k][j];
                }
                int curSum = 0, curMax = INT_MIN;
                set<int> s;
                s.insert(0);
                for (auto a : sum) {
                    curSum += a;
                    auto it = s.lower_bound(curSum - k);
                    if (it != s.end()) curMax = max(curMax, curSum - *it);
                    s.insert(curSum);
                }
                res = max(res, curMax);
            }
        }
        return res;
    }
};

本文转自博客园Grandyang的博客,原文链接:最大矩阵和不超过K[LeetCode] Max Sum of Rectangle No Larger Than K ,如需转载请自行联系原博主。

相关文章
|
7月前
|
算法
力扣240 搜索二维矩阵II
力扣240 搜索二维矩阵II
|
7月前
|
算法 测试技术 C#
【二分查找】LeetCode1970:你能穿过矩阵的最后一天
【二分查找】LeetCode1970:你能穿过矩阵的最后一天
|
7月前
leetcode-329:矩阵中的最长递增路径
leetcode-329:矩阵中的最长递增路径
58 0
|
4月前
|
存储 算法 NoSQL
LeetCode第73题矩阵置零
文章介绍了LeetCode第73题"矩阵置零"的解法,通过使用矩阵的第一行和第一列作为标记来记录哪些行或列需要置零,从而在不增加额外空间的情况下解决问题。
LeetCode第73题矩阵置零
|
2月前
|
算法 C++
Leetcode第59题(螺旋矩阵2)
这篇文章介绍了解决LeetCode第59题“螺旋矩阵II”的算法,通过C++编程实现按顺时针顺序填充一个n x n的正方形矩阵。
18 0
|
4月前
|
算法 Java
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
57 6
|
4月前
|
算法 JavaScript Python
【Leetcode刷题Python】79. 单词搜索和剑指 Offer 12. 矩阵中的路径
Leetcode第79题"单词搜索"的Python解决方案,使用回溯算法在给定的二维字符网格中搜索单词,判断单词是否存在于网格中。
55 4
|
4月前
|
算法 Python
【Leetcode刷题Python】73. 矩阵置零
本文介绍了LeetCode第73题的解法,题目要求在给定矩阵中将所有值为0的元素所在的行和列全部置为0,并提供了一种原地算法的Python实现。
38 0
【Leetcode刷题Python】73. 矩阵置零
|
6月前
|
算法
力扣经典150题第三十七题:矩阵置零
力扣经典150题第三十七题:矩阵置零
39 2
|
6月前
|
存储 数据采集 算法
LeetCode题目73:矩阵置零
LeetCode题目73:矩阵置零