363. 矩形区域不超过 K 的最大数值和
创始人
2024-04-08 23:12:02
0次

文章目录

      • 1. 背
      • 2. 题目
      • 3. 答案

1. 背

这道题很麻烦。首先搞到每个点的前缀和,此时的复杂度就是O(m*n),如果要把所有的矩形子集都判断算一遍,那就是先固定左上角的节点,再遍历右下角的节点,复杂度就是O(m2n2)O(m^2n^2)O(m2n2),但是这道题要想办法降一下,降成O(nlog2n)O(nlog_2^n)O(nlog2n​),总之就是把一个边降下来,这道题要用前者会超时的。

这里的边界都是闭区间的。m是行,n是列,先遍历矩形的上边界,就是for(int up=0;up,第二个for就是矩阵的下边界了,就是for(int down=0;down。

O(m2n2)O(m^2n^2)O(m2n2)的方法下个步骤就是for矩阵的左边界,再for矩阵的右边界。现在要想办法把它们降下来。现在的这道题就很像leetcode第一题了,给一个矩阵,用O(n)O(n)O(n)的复杂度找出和为k的两个数。如果把两数之和改成获取小于k的最大值,复杂度就是O(log2n)O(log_2^n)O(log2n​),把所有数据加入到红黑树中,用lower_bound找到那个数就OK了。

但是目前是矩阵啊,和上面的两数之和还是不一样,那就要想办法把它们从二维变成一维的。矩阵的左边界是SlS_lSl​,右边界是SrS_rSr​,第三个for遍历右边界(即SrS_rSr​),那么问题就变成了怎么在log2nlog_2^nlog2n​的复杂度找到左边界SlS_lSl​。现在就要开始释放一向箔了,因为左边界的移动是以列为单位的,即SlS_lSl​左移一下就是左移一列,那么如果我现在从上往下压,一维数组的每一位表示这一列的和,这虽然是一维的,但也能起到二维的效果。

下一个问题,要找满足Sr−Sl<=kS_r-S_l<=kSr​−Sl​<=k的最大矩阵和,就是Sr−SlS_r-S_lSr​−Sl​的最大值,那就是,固定了SrS_rSr​,那就是满足Sr+k<=SlS_r+k<=S_lSr​+k<=Sl​的最小SlS_lSl​,这不就是lower_bound吗。

这下方法就来了当矩阵的上下边固定后,右边界从0开始遍历for(int r=0;i左边的数值用红黑树存。不过这个红黑树存储的并不是这一列的结果,二十一横行的结果。可以理解为存储的是Si。因为计算时使用的是SlS_lSl​和SrS_rSr​,所以当需要SlS_lSl​减去SrS_rSr​时,


(下面是理论的分析,但是这次实在是不想搞了。感觉现在的代码是左开右闭,但是好像并不是,因为这个区间的问题,需要在set中加一个0。)

这个SlS_lSl​和SrS_rSr​当作一维时表示的是(0,l],这个左开右闭很有讲究,这样当Sr−SlS_r-S_lSr​−Sl​恰好表示[l,r]。

2. 题目

给你一个 m x n 的矩阵 matrix 和一个整数 k ,找出并返回矩阵内部矩形区域的不超过 k 的最大数值和。

题目数据保证总会存在一个数值和不超过 k 的矩形区域。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/max-sum-of-rectangle-no-larger-than-k
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

3. 答案

class Solution {
public:
int maxSumSubmatrix(const vector>& matrix, int k) {int row = matrix.size(), col=matrix[0].size();vector>dp(row,vector(col,0));for(int i=0;i=0?dp[i-1][j]:0;auto num2 = j-1>=0?dp[i][j-1]:0;auto num3 = i-1>=0&&j-1>=0?dp[i-1][j-1]:0;dp[i][j] = num1+num2-num3+matrix[i][j];}}int ret = INT_MIN;for(int up=0;upmin_sum;//<这个参数是sl或sr,就是从左到右的,而不是某一列的min_sum.insert(0);for(int r=0;r=0?dp[up-1][r]:0;int sr = dp[down][r] - num;auto it_sl=min_sum.lower_bound(sr-k);if(it_sl!=min_sum.end()){ret = max(ret, sr-*it_sl);}min_sum.insert(sr);}}}return ret;
}};

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...