forked from shuboc/LeetCode-2
-
Notifications
You must be signed in to change notification settings - Fork 1
/
max-sum-of-sub-matrix-no-larger-than-k.py
103 lines (86 loc) · 3.24 KB
/
max-sum-of-sub-matrix-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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# Time: O(min(m, n)^2 * max(m, n) * log(max(m, n)))
# Space: O(max(m, n))
from bisect import bisect_left, insort
class Solution(object):
def maxSumSubmatrix(self, matrix, k):
"""
:type matrix: List[List[int]]
:type k: int
:rtype: int
"""
if not matrix:
return 0
m = min(len(matrix), len(matrix[0]))
n = max(len(matrix), len(matrix[0]))
result = float("-inf")
for i in xrange(m):
sums = [0] * n
for j in xrange(i, m):
for l in xrange(n):
sums[l] += matrix[j][l] if m == len(matrix) else matrix[l][j]
# Find the max subarray no more than K.
accu_sum_set, accu_sum = [0], 0
for sum in sums:
accu_sum += sum
it = bisect_left(accu_sum_set, accu_sum - k) # Time: O(logn)
if it != len(accu_sum_set):
result = max(result, accu_sum - accu_sum_set[it])
insort(accu_sum_set, accu_sum) # Time: O(n)
return result
# Time: O(min(m, n)^2 * max(m, n) * log(max(m, n))) ~ O(min(m, n)^2 * max(m, n)^2)
# Space: O(max(m, n))
class Solution_TLE(object):
def maxSumSubmatrix(self, matrix, k):
"""
:type matrix: List[List[int]]
:type k: int
:rtype: int
"""
class BST(object): # not avl, rbtree
def __init__(self, val):
self.val = val
self.left = None
self.right = None
def insert(self, val): # Time: O(h) = O(logn) ~ O(n)
curr = self
while curr:
if curr.val >= val:
if curr.left:
curr = curr.left
else:
curr.left = BST(val)
return
else:
if curr.right:
curr = curr.right
else:
curr.right = BST(val)
return
def lower_bound(self, val): # Time: O(h) = O(logn) ~ O(n)
result, curr = None, self
while curr:
if curr.val >= val:
result, curr = curr, curr.left
else:
curr = curr.right
return result
if not matrix:
return 0
m = min(len(matrix), len(matrix[0]))
n = max(len(matrix), len(matrix[0]))
result = float("-inf")
for i in xrange(m):
sums = [0] * n
for j in xrange(i, m):
for l in xrange(n):
sums[l] += matrix[j][l] if m == len(matrix) else matrix[l][j]
# Find the max subarray no more than K.
accu_sum_set = BST(0)
accu_sum = 0
for sum in sums:
accu_sum += sum
node = accu_sum_set.lower_bound(accu_sum - k)
if node:
result = max(result, accu_sum - node.val)
accu_sum_set.insert(accu_sum)
return result