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)相关推荐

  1. 1292. 元素和小于等于阈值的正方形的最大边长-前缀和算法

    1292. 元素和小于等于阈值的正方形的最大边长-前缀和算法 给你一个大小为 m x n 的矩阵 mat 和一个整数阈值 threshold. 请你返回元素总和小于或等于阈值的正方形区域的最大边长:如 ...

  2. LeetCode(1292):元素和小于等于阈值的正方形的最大边长 Maximum Side Length of a Square(Java)

    2020.12.24 LeetCode 从零单刷个人笔记整理(持续更新) github:https://github.com/ChopinXBP/LeetCode-Babel 原地动态规划 + 前缀和 ...

  3. 元素和小于等于阈值的正方形的最大边长(来源:力扣(LeetCode))

    元素和小于等于阈值的正方形的最大边长(来源:力扣(LeetCode)) 给你一个大小为 m x n 的矩阵 mat 和一个整数阈值 threshold.请你返回元素总和小于或等于阈值的正方形区域的最大 ...

  4. leetcode1292. 元素和小于等于阈值的正方形的最大边长(二分法+前缀和)

    给你一个大小为 m x n 的矩阵 mat 和一个整数阈值 threshold. 请你返回元素总和小于或等于阈值的正方形区域的最大边长:如果没有这样的正方形区域,则返回 0 . 示例 2: 输入:ma ...

  5. Leetcode-元素和小于等于阈值的正方形的最大边长(python)

    题目 给你一个大小为 m x n 的矩阵 mat 和一个整数阈值 threshold. 请你返回元素总和小于或等于阈值的正方形区域的最大边长:如果没有这样的正方形区域,则返回 0 . 示例 1: 输入 ...

  6. 【每日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] ...

  7. 已知正方形面积求边长c语言,正方形知道面积怎么求边长.

    2019-10-09阅读(206) 长方形的周长=(长+宽)×2正方形的周长=边长×4长方形的面积=长×宽正方形的面积=边长×边长三角形的面积=底×高÷2平行四边形的面积=底×高梯形的面积=(上底+下 ...

  8. LeetCode 1277. 统计全为 1 的正方形子矩阵(DP)

    1. 题目 给你一个 m * n 的矩阵,矩阵中的元素不是 0 就是 1,请你统计并返回其中完全由 1 组成的 正方形 子矩阵的个数. 示例 1: 输入:matrix = [[0,1,1,1],[1, ...

  9. leetcode 593. Valid Square | 593. 有效的正方形(Java)

    题目 https://leetcode.com/problems/valid-square/ 题解 因为顺序未知,所以可能有四种组合情况.(check时,以四个点顺时针排列为待判断的正方形) clas ...

最新文章

  1. mysql 储存过程
  2. JavaWeb学习总结(一)——JavaWeb开发入门
  3. 【项目管理】绩效域-工件裁剪对照(绩效维度)
  4. java范型_Java知识点总结(Java泛型)
  5. 前端学习(2358):v-bind和v-for
  6. InceptionNet V4
  7. mybatis中经典的9种设计模式
  8. WinForm与WebForm调试输出
  9. 国家市场监管总局:互联网广告不得等倒计时结束才能关闭
  10. 2019胡润女企业家榜公布:碧桂园杨惠妍继续领跑
  11. @Entity,@Indexed @XmlRootElement
  12. sql server 性能分析工具
  13. TwinCAT3安装教程-EtherCAT学习
  14. 无线专题 PCI接口与PCIe接口
  15. 炉石传说 爬取全部卡牌
  16. matlab-高数 diff 方向导数
  17. List集合进行分组
  18. arcgis的炸开多边形功能
  19. HTML爱心动画小玩意儿
  20. 双十一结束了,但AI的退货“打怪之旅”刚刚开始

热门文章

  1. JS_17 ES5,ES6
  2. oracle中defined,Oracle:专栏定义(Oracle: column ambigously defined)
  3. android系统提供了url通信,Android两种HTTP通信,HttpURLConnection和HttpClient
  4. java的import和python的import对比_import导入的是什么
  5. 【洛谷 2661】信息传递
  6. [Swift实际操作]八、实用进阶-(7)使用通知的方法进行对象间的消息传递
  7. 递归多线程实现前缀和
  8. Node.js mimimn图片批量下载爬虫 1.00
  9. Google-优秀移动站点设计10招
  10. 你不知道的 字符集和编码(编码字符集与字符集编码)