# 363. Max Sum of Rectangle No Larger Than K

#### Hard

***

Given an `m x n` matrix `matrix` and an integer `k`, return *the max sum of a rectangle in the matrix such that its sum is no larger than* `k`.

It is **guaranteed** that there will be a rectangle with a sum no larger than `k`.

&#x20;

**Example 1:**

![](https://assets.leetcode.com/uploads/2021/03/18/sum-grid.jpg)

<pre><code>Input: matrix = [[1,0,1],[0,-2,3]], k = 2
<strong>Output:
</strong> 2
<strong>Explanation:
</strong> Because the sum of the blue rectangle [[0, 1], [-2, 3]] is 2, and 2 is the max number no larger than k (k = 2).
</code></pre>

**Example 2:**

<pre><code>Input: matrix = [[2,2,-1]], k = 3
<strong>Output:
</strong> 3
</code></pre>

&#x20;

**Constraints:**

* `m == matrix.length`
* `n == matrix[i].length`
* `1 <= m, n <= 100`
* `-100 <= matrix[i][j] <= 100`
* `-105 <= k <= 105`

&#x20;

**Follow up:** What if the number of rows is much larger than the number of columns?

```python
from sortedcontainers import SortedList
class Solution:
    #.
    def maxSumSubmatrix(self, matrix: List[List[int]], k: int) -> int:
        m, n = len(matrix), len(matrix[0])
        ans = -math.inf
        for r1 in range(m):
            arr = [0] * n  # arr[i] is sum(matrix[r1][c]...matrix[r2][c])
            for r2 in range(r1, m):
                for c in range(n): arr[c] += matrix[r2][c]
                ans = max(ans, self.maxSumSubAarray(arr, n, k))
        return ans

    def maxSumSubAarray(self, arr, n, k):
        right = 0  # PrefixSum so far
        seen = SortedList([0])
        ans = -math.inf
        for i in range(n):
            right += arr[i]
            left = self.ceiling(seen, right - k)  # right - left <= k -> left >= right - k
            if left != None:
                ans = max(ans, right - left)
            seen.add(right)
        return ans

    def ceiling(self, sortedList, key):  # O(logN)
        idx = sortedList.bisect_left(key)
        if idx < len(sortedList): return sortedList[idx]
        return None
```
