这道题暴力法会TLE,先给出这种TLE方案:
1 class Solution: 2 def getMaxPoolVal(self,mat,length,m,n,threshold): 3 maxval = 0 4 for i in range(m-length+1): 5 for j in range(n-length+1): 6 curSquare = 0 7 for x in range(i,i+length):#计算一个方形范围的所有值之和 8 for y in range(j,j+length): 9 curSquare += mat[x][y] 10 if curSquare < threshold: 11 if curSquare > maxval: 12 maxval = curSquare#更新最大值 13 elif curSquare == threshold: 14 return threshold 15 return maxval 16 17 def maxSideLength(self, mat: 'List[List[int]]', threshold: int) -> int: 18 m = len(mat) 19 if m == 0: 20 return 0 21 n = len(mat[0]) 22 maxval = 0 23 maxr = 0 24 r = min(m,n) 25 for t in range(r,0,-1): 26 maxpool = self.getMaxPoolVal(mat,t,m,n,threshold) 27 if maxpool >= maxval: 28 maxval = maxpool 29 if t >= maxr and maxpool != 0: 30 maxr = t 31 if maxval == threshold: 32 return t 33 return maxr
使用前序和方式,Java的可以AC,但是python仍然会TLE,给出这种TLE方案:
1 class Solution: 2 def getMaxPoolVal(self,mat,length,m,n,threshold): 3 for i in range(m-length+1): 4 for j in range(n-length+1): 5 curSquare = mat[i+length][j+length] - mat[i][j+length] - mat[i+length][j] + mat[i][j]#用累加矩阵降低计算量 6 if curSquare <= threshold: 7 return True 8 return False 9 10 def maxSideLength(self, mat: 'List[List[int]]', threshold: int) -> int: 11 m = len(mat) 12 if m == 0: 13 return 0 14 n = len(mat[0]) 15 16 preSum = [[0 for _ in range(n+1)]for _ in range(m+1)] 17 for i in range(1,m+1):#生成累加矩阵 18 sums = 0 19 for j in range(1,n+1): 20 sums += mat[i-1][j-1] 21 preSum[i][j] = preSum[i-1][j] + sums 22 #print(preSum) 23 r = min(m,n) 24 for t in range(r,0,-1):#普通循环 25 if self.getMaxPoolVal(preSum,t,m,n,threshold): 26 return t 27 return 0
python要想AC,或者使用DP或者使用二分搜索:
最后给出AC的解决方案,将上面的24行的循环,改为二分查找:
1 class Solution: 2 def getMaxPoolVal(self,mat,length,m,n,threshold): 3 for i in range(m-length+1): 4 for j in range(n-length+1): 5 curSquare = mat[i+length][j+length] - mat[i][j+length] - mat[i+length][j] + mat[i][j] 6 if curSquare <= threshold: 7 return True 8 return False 9 10 def maxSideLength(self, mat: 'List[List[int]]', threshold: int) -> int: 11 m = len(mat) 12 if m == 0: 13 return 0 14 n = len(mat[0]) 15 16 preSum = [[0 for _ in range(n+1)]for _ in range(m+1)] 17 for i in range(1,m+1): 18 sums = 0 19 for j in range(1,n+1): 20 sums += mat[i-1][j-1] 21 preSum[i][j] = preSum[i-1][j] + sums 22 #print(preSum) 23 r = min(m,n) 24 # for t in range(r,0,-1): 25 # if self.getMaxPoolVal(preSum,t,m,n,threshold): 26 # return t 27 l,h = 0,r#改进为二分查找 28 while l <= h: 29 mid = l + (h - l) // 2 30 if self.getMaxPoolVal(preSum,mid,m,n,threshold): 31 l = mid + 1 32 else: 33 h = mid - 1 34 return h
下面给出参考的方案:
总结:这道题对我来说难度比较大,我只能作出TLE的解。