Max Sum of Rectangle No Larger Than K

hard matrix prefix sum ordered set

Problem

Given a matrix and integer k, find the maximum sum of any rectangular sub-matrix whose sum is ≤ k.

Inputmatrix = [[1,0,1],[0,-2,3]], k = 2
Output2
Best is the 1×1 rectangle of 2? No — try [-2, 3] gives 1, [0, 1] + [-2, 3] gives 2 → 2.

from sortedcontainers import SortedList

def max_sum_submatrix(matrix, k):
    rows, cols = len(matrix), len(matrix[0])
    best = float("-inf")
    for l in range(cols):
        col_sums = [0] * rows
        for r in range(l, cols):
            for i in range(rows):
                col_sums[i] += matrix[i][r]
            seen = SortedList([0])
            prefix = 0
            for v in col_sums:
                prefix += v
                idx = seen.bisect_left(prefix - k)
                if idx < len(seen):
                    best = max(best, prefix - seen[idx])
                seen.add(prefix)
    return best
function maxSumSubmatrix(matrix, k) {
  const rows = matrix.length, cols = matrix[0].length;
  let best = -Infinity;
  for (let l = 0; l < cols; l++) {
    const colSums = new Array(rows).fill(0);
    for (let r = l; r < cols; r++) {
      for (let i = 0; i < rows; i++) colSums[i] += matrix[i][r];
      const seen = [0];
      let prefix = 0;
      for (const v of colSums) {
        prefix += v;
        // find smallest s in seen with prefix - s <= k, i.e. s >= prefix - k
        let lo = 0, hi = seen.length;
        while (lo < hi) { const m = (lo + hi) >> 1; if (seen[m] < prefix - k) lo = m + 1; else hi = m; }
        if (lo < seen.length) best = Math.max(best, prefix - seen[lo]);
        // insert prefix sorted
        let p = 0, q = seen.length;
        while (p < q) { const m = (p + q) >> 1; if (seen[m] < prefix) p = m + 1; else q = m; }
        seen.splice(p, 0, prefix);
      }
    }
  }
  return best;
}
class Solution {
    public int maxSumSubmatrix(int[][] matrix, int k) {
        int rows = matrix.length, cols = matrix[0].length;
        int best = Integer.MIN_VALUE;
        for (int l = 0; l < cols; l++) {
            int[] colSums = new int[rows];
            for (int r = l; r < cols; r++) {
                for (int i = 0; i < rows; i++) colSums[i] += matrix[i][r];
                TreeSet<Integer> seen = new TreeSet<>();
                seen.add(0);
                int prefix = 0;
                for (int v : colSums) {
                    prefix += v;
                    Integer s = seen.ceiling(prefix - k);
                    if (s != null) best = Math.max(best, prefix - s);
                    seen.add(prefix);
                }
            }
        }
        return best;
    }
}
int maxSumSubmatrix(vector<vector<int>>& matrix, int k) {
    int rows = matrix.size(), cols = matrix[0].size();
    int best = INT_MIN;
    for (int l = 0; l < cols; l++) {
        vector<int> colSums(rows, 0);
        for (int r = l; r < cols; r++) {
            for (int i = 0; i < rows; i++) colSums[i] += matrix[i][r];
            set<int> seen{0};
            int prefix = 0;
            for (int v : colSums) {
                prefix += v;
                auto it = seen.lower_bound(prefix - k);
                if (it != seen.end()) best = max(best, prefix - *it);
                seen.insert(prefix);
            }
        }
    }
    return best;
}
Time: O(min(m,n)² · max(m,n) · log(max(m,n))) Space: O(max(m,n))