给你一个大小为 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
提示:
m == mat.length
n == mat[i].length
1 <= m, n <= 300
0 <= mat[i][j] <= 104
0 <= threshold <= 105
二维前缀和。
class Solution:
def maxSideLength(self, mat: List[List[int]], threshold: int) -> int:
m, n = len(mat), len(mat[0])
s = [[0] * 310 for _ in range(310)]
for i in range(m):
for j in range(n):
s[i + 1][j + 1] = s[i][j + 1] + s[i + 1][j] - s[i][j] + mat[i][j]
def check(l):
for i in range(m):
for j in range(n):
if i + l - 1 < m and j + l - 1 < n:
i1, j1 = i + l - 1, j + l - 1
t = s[i1 + 1][j1 + 1] - s[i1 + 1][j] - s[i][j1 + 1] + s[i][j]
if t <= threshold:
return True
return False
left, right = 0, min(m, n)
while left < right:
mid = (left + right + 1) >> 1
if check(mid):
left = mid
else:
right = mid - 1
return left
class Solution {
public int maxSideLength(int[][] mat, int threshold) {
int m = mat.length, n = mat[0].length;
int[][] s = new int[310][310];
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
s[i + 1][j + 1] = s[i][j + 1] + s[i + 1][j] - s[i][j] + mat[i][j];
}
}
int left = 0, right = Math.min(m, n);
while (left < right) {
int mid = (left + right + 1) >> 1;
if (check(mid, s, m, n, threshold)) {
left = mid;
} else {
right = mid - 1;
}
}
return left;
}
private boolean check(int l, int[][] s, int m, int n, int threshold) {
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (i + l - 1 < m && j + l - 1 < n) {
int i1 = i + l - 1, j1 = j + l - 1;
int t = s[i1 + 1][j1 + 1] - s[i1 + 1][j] - s[i][j1 + 1] + s[i][j];
if (t <= threshold) {
return true;
}
}
}
}
return false;
}
}
class Solution {
public:
int maxSideLength(vector<vector<int>>& mat, int threshold) {
int m = mat.size(), n = mat[0].size();
vector<vector<int>> s(310, vector<int>(310));
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
s[i + 1][j + 1] = s[i][j + 1] + s[i + 1][j] - s[i][j] + mat[i][j];
int left = 0, right = min(m, n);
while (left < right) {
int mid = left + right + 1 >> 1;
if (check(mid, s, m, n, threshold))
left = mid;
else
right = mid - 1;
}
return left;
}
bool check(int l, vector<vector<int>>& s, int m, int n, int threshold) {
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (i + l - 1 < m && j + l - 1 < n) {
int i1 = i + l - 1, j1 = j + l - 1;
int t = s[i1 + 1][j1 + 1] - s[i1 + 1][j] - s[i][j1 + 1] + s[i][j];
if (t <= threshold) return true;
}
}
}
return false;
}
};
func maxSideLength(mat [][]int, threshold int) int {
m, n := len(mat), len(mat[0])
s := make([][]int, 310)
for i := 0; i < len(s); i++ {
s[i] = make([]int, 310)
}
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
s[i+1][j+1] = s[i][j+1] + s[i+1][j] - s[i][j] + mat[i][j]
}
}
left, right := 0, min(m, n)
check := func(l int) bool {
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
if i+l-1 < m && j+l-1 < n {
i1, j1 := i+l-1, j+l-1
t := s[i1+1][j1+1] - s[i1+1][j] - s[i][j1+1] + s[i][j]
if t <= threshold {
return true
}
}
}
}
return false
}
for left < right {
mid := (left + right + 1) >> 1
if check(mid) {
left = mid
} else {
right = mid - 1
}
}
return left
}
func min(a, b int) int {
if a < b {
return a
}
return b
}