zoukankan      html  css  js  c++  java
  • 363. Max Sum of Rectangle No Larger Than K

    问题:

    给定二维数组,

    求其中子矩形中元素和不大于K 的最大和。

    Example 1:
    Input: matrix = [[1,0,1],[0,-2,3]], k = 2
    Output: 2
    Explanation: Because the sum of the blue rectangle [[0, 1], [-2, 3]] is 2, and 2 is the max number no larger than k (k = 2).
    
    Example 2:
    Input: matrix = [[2,2,-1]], k = 3
    Output: 3
     
    
    Constraints:
    m == matrix.length
    n == matrix[i].length
    1 <= m, n <= 100
    -100 <= matrix[i][j] <= 100
    -10^5 <= k <= 10^5
    

      

    example 1:

    解法:preSum(前缀和)

    以往我们使用preSum方法,都是在一维数组中。

    而这次需要在二维数组中使用,则需要进行降维。

     固定列的范围:lj~rj (外层再进行遍历所有范围可能)

    对于任意行 i:将多列压缩成一列->preColSum[i]

    这样,我们得到多行的列压缩结果。

    这样,就成了一维。{0,2,6,-8,4,6}

    对这个一维数组,进行前缀和求解即可。

    求任意区间的和<=K, 中求最大和。

    这里,我们使用二分查找,进行快速查找。

    利用辅助前缀和set:preSum

    来保存已经遍历过的前缀和。

    那么要求的,即为前缀和preSum中 >=当前前缀和curSum-K

    这里,由于set是排序set,使用lower_bound即可找到第一个>=curSum-K的数x

    即 K>=curSum-x

    再将当前前缀和curSum加入已遍历前缀和set:preSum。

    代码参考:

     1 class Solution {
     2 public:
     3     int maxSumSubmatrix(vector<vector<int>>& matrix, int k) {
     4         int res=INT_MIN;
     5         int n = matrix.size(), m = matrix[0].size();
     6         for(int lj=0; lj<m; lj++) {
     7             vector<int> preColSums(n,0);//->==rows |<-
     8             //combine left:<- col[lj ~ rj]
     9             for(int rj=lj; rj<m; rj++) {
    10                 //in one row, width=[lj, rj]
    11                 for(int i=0; i<n; i++) {
    12                     preColSums[i] += matrix[i][rj];
    13                 }
    14                 set<int> preSum={0};//preSum need a 0 as minus data
    15                 int curSum=0;
    16                 //combine up ↑
    17                 for(int i=0; i<n; i++) {
    18                     curSum+=preColSums[i];
    19                     auto it = preSum.lower_bound(curSum-k);
    20                     if(it!=preSum.end()) res=max(res, curSum-*it);
    21                     preSum.insert(curSum);
    22                 }
    23             }
    24         }
    25         return res;
    26     }
    27 };
  • 相关阅读:
    dsu on tree
    bzoj3527 [Zjoi2014]力
    bzoj3527 [Zjoi2014]力
    114.遍历文件夹并批量修改文件名
    25.八皇后问题
    24.C语言最全排序方法小结(不断更新)
    112.备忘录设计模式
    110.文件搜索,系统大小获取,以及病毒行为
    109.vprintf vfprintf vscanf vfscanf
    108.sqllite3(C语言数据库库)详解
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14670766.html
Copyright © 2011-2022 走看看