1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold

  • Array
  • Binary Search
  • Matrix
  • Prefix Sum
TIME
O(m × n × log(min(m, n)))
SPACE
O(m × n)
problem on leetcode ↗source on github ↗

Intuition

Use 2D prefix sum to compute any submatrix sum in O(1). Binary search on the side length since if a square of size L works, all smaller squares also work (monotonic property).

Solution

  1. Build prefix sum matrix: pref[i][j] = sum of all elements in submatrix from (0,0) to (i-1,j-1).

  2. Binary search on side length: Search for the maximum L where at least one L×L square has sum ≤ threshold.

  3. Check if side L is possible: For each possible top-left corner, compute the L×L square sum using prefix sum formula:

    sum = pref[i+L][j+L] - pref[i][j+L] - pref[i+L][j] + pref[i][j]
  4. Return maximum valid side: The largest L where possible(L) returns true.

Complexity

  • Time: O(m × n × log(min(m, n))), prefix sum O(mn), binary search O(log(min)) with O(mn) check each
  • Space: O(m × n), prefix sum matrix

Edge Cases

  • All elements exceed threshold → return 0
  • Single cell ≤ threshold → return 1
  • Entire matrix sum ≤ threshold → return min(m, n)

Code

from typing import List


class Solution:
    def maxSideLength(self, mat: List[List[int]], threshold: int) -> int:
        """
        1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold
        Time: O(m × n × log(min(m, n)))
        Space: O(m × n)
        """
        m, n = len(mat), len(mat[0])

        pref = [[0] * (n + 1) for _ in range(m + 1)]
        for i in range(1, m + 1):
            for j in range(1, n + 1):
                pref[i][j] = (
                    mat[i - 1][j - 1]
                    + pref[i - 1][j]
                    + pref[i][j - 1]
                    - pref[i - 1][j - 1]
                )

        def possible(L: int) -> bool:
            for i in range(m - L + 1):
                for j in range(n - L + 1):
                    total = (
                        pref[i + L][j + L]
                        - pref[i][j + L]
                        - pref[i + L][j]
                        + pref[i][j]
                    )
                    if total <= threshold:
                        return True
            return False

        low, high = 0, min(m, n)
        ans = 0

        while low <= high:
            mid = (low + high) // 2
            if possible(mid):
                ans = mid
                low = mid + 1
            else:
                high = mid - 1

        return ans