diff --git a/misc/max_area_histogram.py b/misc/max_area_histogram.py index ce342ab..0769e36 100644 --- a/misc/max_area_histogram.py +++ b/misc/max_area_histogram.py @@ -10,7 +10,7 @@ """ -# hist represented as ith bar has height h(i) +# hist represented as ith bar has height h(i) histogram = [6, 4, 2, 1, 3, 4, 5, 2, 6] """ @@ -21,26 +21,29 @@ 4. compute max area """ -def get_L(hist): - L = [0]*len(hist) - for i in range(1, len(hist)): - if hist[i] > hist[i-1]: - L[i] = i + +def find_Li(hist, i): + left_edge = 0 + for j in range(i-1, -1, -1): + if hist[j] >= hist[i]: + left_edge += 1 else: - L[i] = L[i-1] - return L + return left_edge + + return left_edge -print get_L(histogram) def find_Ri(hist, i): right_edge = 0 - for j in range(i+1, len(hist)): + for j in range(i + 1, len(hist)): if hist[j] >= hist[i]: right_edge += 1 else: return right_edge + return right_edge + def get_area(hist, i): return hist[i] * (find_Li(hist, i) + find_Ri(hist, i) + 1) @@ -53,6 +56,7 @@ def get_max_area(hist): max_area = area return max_area + def max_rectangle_area(histogram): """Find the area of the largest rectangle that fits entirely under the histogram. @@ -61,21 +65,21 @@ def max_rectangle_area(histogram): stack = [] top = lambda: stack[-1] max_area = 0 - pos = 0 # current position in the histogram + pos = 0 # current position in the histogram for pos, height in enumerate(histogram): - start = pos # position where rectangle starts + start = pos # position where rectangle starts while True: - if not stack or height > top().height: - stack.append(Info(start, height)) # push - elif stack and height < top().height: - max_area = max(max_area, top().height*(pos-top().start)) + if not stack or height > top()[1]: + stack.append((start, height)) # push + elif stack and height < top()[1]: + max_area = max(max_area, top()[1] * (pos - top()[0])) start, _ = stack.pop() continue - break # height == top().height goes here + break # height == top().height goes here pos += 1 for start, height in stack: - max_area = max(max_area, height*(pos-start)) + max_area = max(max_area, height * (pos - start)) return max_area