-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathanswer.py
108 lines (91 loc) · 3.47 KB
/
answer.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
103
104
105
106
107
108
#!/usr/bin/python3
#------------------------------------------------------------------------------
# Solution O(n) Stack Solution
#------------------------------------------------------------------------------
class Solution(object):
def largestRectangleArea(self, heights):
"""
:type heights: List[int]
:rtype: int
"""
heights.append(0)
stack = [-1]
result = 0
for i in range(len(heights)):
while heights[i] < heights[stack[-1]]:
h = heights[stack.pop()]
w = i - stack[-1] - 1
result = max(result, h * w)
stack.append(i)
return result
#------------------------------------------------------------------------------
# Solution O(n) Kinda DP Solution
#------------------------------------------------------------------------------
class Solution(object):
def largestRectangleArea(self, heights):
"""
:type heights: List[int]
:rtype: int
"""
result = 0
# Left and right will be a cache to hold the number of bars to left and right >= curr height
left = [1 for _ in range(len(heights))]
right = [1 for _ in range(len(heights))]
# Calculate left
for i in range(len(heights)):
l = i-1
# Grow as far left as possible
# We make jumps based on the previously computed left values
while l >= 0:
if heights[l] >= heights[i]:
left[i] += left[l]
l -= left[l]
else:
break
# Calculate right
for i in range(len(heights)):
r = i+1
# Grow as far right as possible
# We make jumps based on the previously computed right values
while r < len(heights):
if heights[r] >= heights[i]:
right[i] += right[r]
r += right[r]
else:
break
# Now we can iterate through all of our possible rectangles
# We calculate our areas with our height * width (left+right)
for i in range(len(heights)):
result = max(result, heights[i] * (left[i] + right[i] - 1))
return result
#------------------------------------------------------------------------------
# Brute Force Solution (O(n^2))
#------------------------------------------------------------------------------
class Solution(object):
def largestRectangleArea(self, heights):
"""
:type heights: List[int]
:rtype: int
"""
result = 0
# Find the max area for each bar i
for i in range(len(heights)):
area = heights[i]
l, r = i-1, i+1
# Grow as far left as possible
while l >= 0:
if heights[l] >= heights[i]:
area += heights[i]
l -= 1
else:
break
# Grow as far right as possible
while r < len(heights):
if heights[r] >= heights[i]:
area += heights[i]
r += 1
else:
break
result = max(result, area)
return result
#------------------------------------------------------------------------------