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
.
For example:
matrix = [[1,0,1],[0,-2,3]], k = 2
Output: 2
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).
As another example:
matrix = [[2,2,-1]], k = 3
Output: 3
Constraints:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 100
-100 <= matrix[i][j] <= 100
-10^5 <= k <= 10^5
Follow up: What if the number of rows is much larger than the number of columns?
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute-force strategy for this problem is all about trying out every single possible rectangle within the bigger shape. We'll calculate the sum of each rectangle and see if it fits our requirement. It's like trying every single combination until we find the best one.
Here's how the algorithm would work step-by-step:
def max_sub_matrix_no_larger_than_k_brute_force(matrix, k_value):
max_sum_no_larger_than_k = float('-inf')
number_of_rows = len(matrix)
number_of_cols = len(matrix[0])
for top_row in range(number_of_rows):
for left_col in range(number_of_cols):
for bottom_row in range(top_row, number_of_rows):
for right_col in range(left_col, number_of_cols):
rectangle_sum = 0
# Calculate the sum of the current rectangle
for row in range(top_row, bottom_row + 1):
for col in range(left_col, right_col + 1):
rectangle_sum += matrix[row][col]
# We filter for sums <= k_value
if rectangle_sum <= k_value:
# Update max_sum if needed
max_sum_no_larger_than_k = max(max_sum_no_larger_than_k, rectangle_sum)
return max_sum_no_larger_than_k
The key idea is to efficiently check rectangle sums by pre-calculating sums and using a sorted set data structure. We iterate through all possible pairs of columns to define the rectangle's width, and then use binary search to efficiently find the rectangle's height that gets us as close as possible to the target sum K without exceeding it.
Here's how the algorithm would work step-by-step:
from sortedcontainers import SortedSet
def max_sum_submatrix(matrix, target):
number_of_rows = len(matrix)
number_of_cols = len(matrix[0]) if number_of_rows > 0 else 0
max_sum_no_larger_than_k = float('-inf')
for left_col in range(number_of_cols):
row_sums = [0] * number_of_rows
for right_col in range(left_col, number_of_cols):
for row in range(number_of_rows):
row_sums[row] += matrix[row][right_col]
current_sum = 0
seen_sums = SortedSet([0])
for row_sum in row_sums:
current_sum += row_sum
# Find a prefix sum that gets us closest to target without exceeding
prefix_sum = current_sum - target
iterator = seen_sums.lower_bound(prefix_sum)
if iterator != len(seen_sums):
max_sum_no_larger_than_k = max(max_sum_no_larger_than_k, current_sum - seen_sums[iterator])
seen_sums.add(current_sum)
return max_sum_no_larger_than_k
Case | How to Handle |
---|---|
Null or empty matrix | Return negative infinity as there's no valid rectangle to sum. |
K is negative | The problem constraints may disallow this; if allowed, handle negative sums correctly within the algorithm. |
Matrix with a single row or single column | Treat the single row/column as a 1D array and apply 1D Kadane-like algorithm with K constraint. |
All elements in the matrix are negative and K is positive | Return the largest negative element or negative infinity if all sums exceed K (in negative terms). |
K is very large compared to the matrix values, such that the entire matrix sum is less than or equal to K | Efficiently calculate the total sum and return it directly. |
Integer overflow when calculating rectangle sums, especially with large matrix dimensions and values | Use long data type to store intermediate rectangle sums to prevent overflow. |
The problem has no solution where a sum <= K exists. | Return negative infinity to indicate that no rectangle satisfies the condition. |
Maximum-sized matrix that exceeds memory limits when calculating prefix sums. | Instead of precomputing the entire prefix sum, calculate the necessary sums on-the-fly or use a divide-and-conquer strategy to reduce memory usage. |