这道题暴力法会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

参考:https://leetcode.com/problems/maximum-side-length-of-a-square-with-sum-less-than-or-equal-to-threshold/discuss/451843/Java-PrefixSum-solution

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

 

下面给出参考的方案:

二分搜索方案:https://leetcode.com/problems/maximum-side-length-of-a-square-with-sum-less-than-or-equal-to-threshold/discuss/451942/python-O(m*n*log(min(m-n)))

dp方案:https://leetcode.com/problems/maximum-side-length-of-a-square-with-sum-less-than-or-equal-to-threshold/discuss/451927/python-dp-accept

与本题相近的Java方案:https://leetcode.com/problems/maximum-side-length-of-a-square-with-sum-less-than-or-equal-to-threshold/discuss/451871/Java-sum%2Bbinary-O(m*n*log(min(mn)))

总结:这道题对我来说难度比较大,我只能作出TLE的解。

posted on 2019-12-15 13:08  Sempron2800+  阅读(301)  评论(0编辑  收藏  举报