-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy path363.max-sum-of-rectangle-no-larger-than-k.py
81 lines (66 loc) · 2.62 KB
/
363.max-sum-of-rectangle-no-larger-than-k.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#
# @lc app=leetcode id=363 lang=python3
#
# [363] Max Sum of Rectangle No Larger Than K
#
# @lc code=start
# TAGS: Array, Binary Search, Dynamic Programming, Matrix, Ordered Set
# REVIEWME: Ordered Set
import sortedcontainers
class Solution:
# LTE. Time: O(R*R*C*C)
def maxSumSubmatrix(self, matrix: List[List[int]], k: int) -> int:
R, C = len(matrix), len(matrix[0])
prefix_mat = [[0] * (C + 1)]
for row in matrix:
temp = [0]
for val in row:
temp.append(temp[-1] + val)
prefix_mat.append(temp)
for c in range(1, C + 1):
for r in range(1, R + 1):
prefix_mat[r][c] += prefix_mat[r - 1][c]
ans = float("-inf")
for r in range(1, R + 1):
for c in range(1, C + 1):
for nr in range(r, R + 1):
for nc in range(c, C + 1):
val = prefix_mat[nr][nc] \
- prefix_mat[nr][c - 1] \
- prefix_mat[r - 1][nc] \
+ prefix_mat[r - 1][c - 1]
if val > ans and val <= k:
ans = val
return ans
# 7552 ms, 5.09%. Time: O(R*R*C*logC). Space: O(R*C)
def maxSumSubmatrix(self, matrix: List[List[int]], k: int) -> int:
R, C = len(matrix), len(matrix[0])
# Create prefix sum matrix
prefix_mat = [[0] * (C + 1)]
for row in matrix:
temp = [0]
for val in row:
temp.append(temp[-1] + val)
prefix_mat.append(temp)
for c in range(1, C + 1):
for r in range(1, R + 1):
prefix_mat[r][c] += prefix_mat[r - 1][c]
# Try different matrix size (by adjusting rows)
ans = float("-inf")
for r1 in range(0, R):
for r2 in range(r1 + 1, R + 1):
visited = sortedcontainers.SortedList([])
# Loop through each column
for c in range(C + 1):
# sum of this rectangle
cumm_val = prefix_mat[r2][c] - prefix_mat[r1][c]
# binarysearch visited to find value such that cumm_val - val near K
index = visited.bisect_left(cumm_val - k)
if index < len(visited) and k < cumm_val - visited[index]:
index += 1
if index < len(visited):
ans = max(ans, cumm_val - visited[index])
# add current cumm_val to visited
visited.add(cumm_val)
return ans
# @lc code=end