LeetCode 1292. 元素和小于等于阈值的正方形的最大边长(DP)
1. 题目
给你一个大小为 m x n 的矩阵 mat 和一个整数阈值 threshold。
请你返回元素总和小于或等于阈值的正方形区域的最大边长;
如果没有这样的正方形区域,则返回 0 。
示例 1:
输入:mat = [[1,1,3,2,4,3,2],[1,1,3,2,4,3,2],[1,1,3,2,4,3,2]],
threshold = 4
输出:2
解释:总和小于 4 的正方形的最大边长为 2,如图所示。示例 2:
输入:mat = [[2,2,2,2,2],[2,2,2,2,2],[2,2,2,2,2],[2,2,2,2,2],[2,2,2,2,2]],
threshold = 1
输出:0示例 3:
输入:mat = [[1,1,1,1],[1,0,0,0],[1,0,0,0],[1,0,0,0]],
threshold = 6
输出:3示例 4:
输入:mat = [[18,70],[61,1],[25,85],[14,40],[11,96],[97,96],[63,45]],
threshold = 40184
输出:2提示:
1 <= m, n <= 300
m == mat.length
n == mat[i].length
0 <= mat[i][j] <= 10000
0 <= threshold <= 10^5
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-side-length-of-a-square-with-sum-less-than-or-equal-to-threshold
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2. 解题
- 先求出左上角(0,0)到任意位置组成的矩形的和
- 然后遍历所有的 左上顶点,再遍历正方形的边长
- 时间复杂度 O(mn∗min(m,n))O(mn*min(m,n))O(mn∗min(m,n))
class Solution {public:int maxSideLength(vector<vector<int>>& mat, int threshold) {int m = mat.size(), n = mat[0].size(), i, j, maxlen = 0, len = 0;vector<vector<int>> sum(m,vector<int>(n,0));//先求第一行、第一列的前缀和for(j = 0; j < n; ++j)sum[0][j] = (j > 0 ? sum[0][j-1] : 0) + mat[0][j];//注意加括号for(i = 1; i < m; ++i)sum[i][0] = sum[i-1][0] + mat[i][0];//剩余位置的前缀和for(i = 1; i < m; ++i)for(j = 1; j < n; ++j)sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1]+mat[i][j];int ni, nj, sumofarea;//遍历左上角位置for(i = 0; i < m; ++i)for(j = 0; j < n; ++j)for(len = 1; len <= min(m,n); ++len){ //遍历正方形边长ni = i+len-1;//右下角nj = j+len-1;if(ni < m && nj < n){sumofarea = sum[ni][nj]-(i>0?sum[i-1][nj]:0)-(j>0?sum[ni][j-1]:0)+((i>0&&j>0) ? sum[i-1][j-1] : 0);//由前缀和推出正方形的和if(sumofarea <= threshold){maxlen = max(maxlen, len);if(maxlen == min(m,n))return maxlen;}}elsebreak;}return maxlen;}
};
1104 ms 22.6 MB
- 优化,下一个顶点,遍历的长度从maxlen+1开始找
- 和是增大的,一旦大于阈值就不必往下找了
- 这种解法的时间复杂度为 O(mn)O(mn)O(mn),可以参考官方题解分析,比最内层循环采用二分查找的方式O(mnlog(min(m,n))O(mn\log(min(m,n))O(mnlog(min(m,n))更优
class Solution {public:int maxSideLength(vector<vector<int>>& mat, int threshold) {int m = mat.size(), n = mat[0].size(), i, j, maxlen = 0, len = 0;vector<vector<int>> sum(m,vector<int>(n,0));for(j = 0; j < n; ++j)sum[0][j] = (j > 0 ? sum[0][j-1] : 0) + mat[0][j];for(i = 1; i < m; ++i)sum[i][0] = sum[i-1][0] + mat[i][0];for(i = 1; i < m; ++i)for(j = 1; j < n; ++j)sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1]+mat[i][j];int ni, nj, sumofarea;for(i = 0; i < m; ++i)for(j = 0; j < n; ++j)for(len = maxlen+1; len <= min(m,n); ++len){ni = i+len-1;nj = j+len-1;if(ni < m && nj < n && sum[ni][nj]-(i>0?sum[i-1][nj]:0)-(j>0?sum[ni][j-1]:0)+(i>0&&j>0 ? sum[i-1][j-1] : 0) <= threshold){maxlen = max(maxlen, len);if(maxlen == min(m,n))return maxlen;}elsebreak;}return maxlen;}
};
176 ms 22.5 MB
python3 解答
class Solution:# py3def maxSideLength(self, mat: List[List[int]], threshold: int) -> int:m, n = len(mat), len(mat[0])maxlen = 0prefixsum = [[0]*n for _ in range(m)]prefixsum[0][0] = mat[0][0]for j in range(1,n):prefixsum[0][j] = prefixsum[0][j-1]+mat[0][j]for i in range(1,m):prefixsum[i][0] = prefixsum[i-1][0]+mat[i][0]for i in range(1,m):for j in range(1,n):prefixsum[i][j] = prefixsum[i-1][j]+prefixsum[i][j-1]-prefixsum[i-1][j-1]+mat[i][j]for i in range(m):for j in range(n):length = maxlen+1while length <= min(m,n):ni = i+length-1nj = j+length-1if ni<m and nj<n and prefixsum[ni][nj]-(prefixsum[i-1][nj] if i > 0 else 0)-(prefixsum[ni][j-1] if j > 0 else 0)+(prefixsum[i-1][j-1] if i>0 and j>0 else 0) <= threshold:maxlen = max(maxlen, length)if maxlen == min(m,n):return maxlenelse:breaklength += 1return maxlen
1092 ms 19.3 MB
LeetCode 1292. 元素和小于等于阈值的正方形的最大边长(DP)相关推荐
- 1292. 元素和小于等于阈值的正方形的最大边长-前缀和算法
1292. 元素和小于等于阈值的正方形的最大边长-前缀和算法 给你一个大小为 m x n 的矩阵 mat 和一个整数阈值 threshold. 请你返回元素总和小于或等于阈值的正方形区域的最大边长:如 ...
- LeetCode(1292):元素和小于等于阈值的正方形的最大边长 Maximum Side Length of a Square(Java)
2020.12.24 LeetCode 从零单刷个人笔记整理(持续更新) github:https://github.com/ChopinXBP/LeetCode-Babel 原地动态规划 + 前缀和 ...
- 元素和小于等于阈值的正方形的最大边长(来源:力扣(LeetCode))
元素和小于等于阈值的正方形的最大边长(来源:力扣(LeetCode)) 给你一个大小为 m x n 的矩阵 mat 和一个整数阈值 threshold.请你返回元素总和小于或等于阈值的正方形区域的最大 ...
- leetcode1292. 元素和小于等于阈值的正方形的最大边长(二分法+前缀和)
给你一个大小为 m x n 的矩阵 mat 和一个整数阈值 threshold. 请你返回元素总和小于或等于阈值的正方形区域的最大边长:如果没有这样的正方形区域,则返回 0 . 示例 2: 输入:ma ...
- Leetcode-元素和小于等于阈值的正方形的最大边长(python)
题目 给你一个大小为 m x n 的矩阵 mat 和一个整数阈值 threshold. 请你返回元素总和小于或等于阈值的正方形区域的最大边长:如果没有这样的正方形区域,则返回 0 . 示例 1: 输入 ...
- 【每日DP】day3 P1387 最大正方形(奇怪的DP增加了 / 二维前缀和)难度⭐⭐★
奇怪的DP增加了 这道题,刚看见真是一脸懵逼,看了题解才明白. 本题中神奇的转移方程是: f[i][j]=min(min(f[i][j−1],f[i−1][j]),f[i−1][j−1])+1f[i] ...
- 已知正方形面积求边长c语言,正方形知道面积怎么求边长.
2019-10-09阅读(206) 长方形的周长=(长+宽)×2正方形的周长=边长×4长方形的面积=长×宽正方形的面积=边长×边长三角形的面积=底×高÷2平行四边形的面积=底×高梯形的面积=(上底+下 ...
- LeetCode 1277. 统计全为 1 的正方形子矩阵(DP)
1. 题目 给你一个 m * n 的矩阵,矩阵中的元素不是 0 就是 1,请你统计并返回其中完全由 1 组成的 正方形 子矩阵的个数. 示例 1: 输入:matrix = [[0,1,1,1],[1, ...
- leetcode 593. Valid Square | 593. 有效的正方形(Java)
题目 https://leetcode.com/problems/valid-square/ 题解 因为顺序未知,所以可能有四种组合情况.(check时,以四个点顺时针排列为待判断的正方形) clas ...
最新文章
- mysql 储存过程
- JavaWeb学习总结(一)——JavaWeb开发入门
- 【项目管理】绩效域-工件裁剪对照(绩效维度)
- java范型_Java知识点总结(Java泛型)
- 前端学习(2358):v-bind和v-for
- InceptionNet V4
- mybatis中经典的9种设计模式
- WinForm与WebForm调试输出
- 国家市场监管总局:互联网广告不得等倒计时结束才能关闭
- 2019胡润女企业家榜公布:碧桂园杨惠妍继续领跑
- @Entity,@Indexed @XmlRootElement
- sql server 性能分析工具
- TwinCAT3安装教程-EtherCAT学习
- 无线专题 PCI接口与PCIe接口
- 炉石传说 爬取全部卡牌
- matlab-高数 diff 方向导数
- List集合进行分组
- arcgis的炸开多边形功能
- HTML爱心动画小玩意儿
- 双十一结束了,但AI的退货“打怪之旅”刚刚开始
热门文章
- JS_17 ES5,ES6
- oracle中defined,Oracle:专栏定义(Oracle: column ambigously defined)
- android系统提供了url通信,Android两种HTTP通信,HttpURLConnection和HttpClient
- java的import和python的import对比_import导入的是什么
- 【洛谷 2661】信息传递
- [Swift实际操作]八、实用进阶-(7)使用通知的方法进行对象间的消息传递
- 递归多线程实现前缀和
- Node.js mimimn图片批量下载爬虫 1.00
- Google-优秀移动站点设计10招
- 你不知道的 字符集和编码(编码字符集与字符集编码)