- Identify the ordered answer range or sorted search domain.
- Write a predicate whose truth changes only once.
- Move the appropriate boundary after each midpoint check and return the final feasible position.
Code notes
- 104 lines of Python from the credited upstream file max-sum-of-sub-matrix-no-larger-than-k.py.
- The implementation visibly relies on sequence storage.
- No explicit loop blocks detected.
Complexity
Multiply the logarithmic number of midpoint checks by the cost of one predicate evaluation.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
123 4from bisect import bisect_left, insort5 6class Solution(object):7 def maxSumSubmatrix(self, matrix, k):8 """9 :type matrix: List[List[int]]10 :type k: int11 :rtype: int12 """13 if not matrix:14 return 015 16 m = min(len(matrix), len(matrix[0]))17 n = max(len(matrix), len(matrix[0]))18 result = float("-inf")19 20 for i in xrange(m):21 sums = [0] * n22 for j in xrange(i, m):23 for l in xrange(n):24 sums[l] += matrix[j][l] if m == len(matrix) else matrix[l][j]25 26 27 accu_sum_set, accu_sum = [0], 028 for sum in sums:29 accu_sum += sum30 it = bisect_left(accu_sum_set, accu_sum - k) 31 if it != len(accu_sum_set):32 result = max(result, accu_sum - accu_sum_set[it])33 insort(accu_sum_set, accu_sum) 34 35 return result36 37 383940class Solution_TLE(object):41 def maxSumSubmatrix(self, matrix, k):42 """43 :type matrix: List[List[int]]44 :type k: int45 :rtype: int46 """47 class BST(object): 48 def __init__(self, val):49 self.val = val50 self.left = None51 self.right = None52 53 def insert(self, val): 54 curr = self55 while curr:56 if curr.val >= val:57 if curr.left:58 curr = curr.left59 else:60 curr.left = BST(val)61 return62 else:63 if curr.right:64 curr = curr.right65 else:66 curr.right = BST(val)67 return68 69 def lower_bound(self, val): 70 result, curr = None, self71 while curr:72 if curr.val >= val:73 result, curr = curr, curr.left74 else:75 curr = curr.right76 return result77 78 79 if not matrix:80 return 081 82 m = min(len(matrix), len(matrix[0]))83 n = max(len(matrix), len(matrix[0]))84 result = float("-inf")85 86 for i in xrange(m):87 sums = [0] * n88 for j in xrange(i, m):89 for l in xrange(n):90 sums[l] += matrix[j][l] if m == len(matrix) else matrix[l][j]91 92 93 accu_sum_set = BST(0)94 accu_sum = 095 for sum in sums:96 accu_sum += sum97 node = accu_sum_set.lower_bound(accu_sum - k)98 if node:99 result = max(result, accu_sum - node.val)100 accu_sum_set.insert(accu_sum)101 102 return result103 104