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 };

 

posted @ 2020-07-05 10:59  habibah_chang  阅读(129)  评论(0编辑  收藏  举报