1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold
问题:
给定一个二维数组,
求其中正方形区域,使得和<=阈值threshold的最长边长。
Example 1: Input: mat = [[1,1,3,2,4,3,2],[1,1,3,2,4,3,2],[1,1,3,2,4,3,2]], threshold = 4 Output: 2 Explanation: The maximum side length of square with sum less than 4 is 2 as shown. Example 2: Input: 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 Output: 0 Example 3: Input: mat = [[1,1,1,1],[1,0,0,0],[1,0,0,0],[1,0,0,0]], threshold = 6 Output: 3 Example 4: Input: mat = [[18,70],[61,1],[25,85],[14,40],[11,96],[97,96],[63,45]], threshold = 40184 Output: 2 Constraints: 1 <= m, n <= 300 m == mat.length n == mat[i].length 0 <= mat[i][j] <= 10000 0 <= threshold <= 10^5
解法:
prefixSum的方法:
prefixSum[x][y]表示锯形(左上角(0,0)右下角(x,y))的和。
所求正方形(左上角(x1,y1)右下角(x2,y2))的和 SquareSum 为:
= prefixSum[x2][y2] - prefixSum[x1][y2] - prefixSum[x2][y1] + prefixSum[x1][y1]
对于每个节点(i,j)【作为正方形左上顶点】我们寻找SquareSum满足条件<=threshold的
即,对每个节点(i,j),我们尝试向右下↘️伸长 len 的距离,
🌟若 i+len 不超过边界m,j+len 不超过边界n,且满足条件 SquareSum(i, j, i+len, j+len)<=threshold
那么res=len,
再增加 len++,继续尝试。
直到不满足上述条件🌟
再尝试下一个节点。以后的尝试,从res+1开始,<=res的情况已经不用再尝试。
附:
那么在这之前,我们得先构造prefixSum
prefixSum的求法(DP)为:
首先初始化第一行和第一列,前0行 or 前0列的prefixSum皆为0
然后:
prefixSum[x][y]=
prefixSum[x-1][y] + prefixSum[x][y-1] - prefixSum[x-1][y-1] + mat[x][y]
代码参考:
1 class Solution { 2 public: 3 int SquareSum(vector<vector<int>>& prefixSum, int x1, int y1, int x2, int y2){ 4 return prefixSum[x2][y2]-prefixSum[x1][y2]-prefixSum[x2][y1]+prefixSum[x1][y1]; 5 } 6 int maxSideLength(vector<vector<int>>& mat, int threshold) { 7 int m=mat.size(), n=mat[0].size(); 8 vector<vector<int>> prefixSum(m+1, vector<int>(n+1,0)); 9 for(int i=1; i<=m; i++){ 10 for(int j=1; j<=n; j++){ 11 prefixSum[i][j]=prefixSum[i][j-1]+prefixSum[i-1][j]-prefixSum[i-1][j-1]+mat[i-1][j-1]; 12 } 13 } 14 int res=0; 15 for(int i=0; i<=m; i++){ 16 for(int j=0; j<=n; j++){ 17 int len=res+1; 18 while(i+len<=m && j+len<=n && SquareSum(prefixSum, i, j, i+len, j+len)<=threshold){ 19 res=len; 20 len++; 21 } 22 } 23 } 24 return res; 25 } 26 };