# 84-largest-rectangle-in-histogram Try it on leetcode ## Description

Given an array of integers heights representing the histogram's bar height where the width of each bar is 1, return the area of the largest rectangle in the histogram.

 

Example 1:

Input: heights = [2,1,5,6,2,3]
Output: 10
Explanation: The above is a histogram where width of each bar is 1.
The largest rectangle is shown in the red area, which has an area = 10 units.

Example 2:

Input: heights = [2,4]
Output: 4

 

Constraints:

## Solution(Python) ```Python class Solution: """ for calculating a rectangle we need both width and height the width of the rectangle will be the difference of index positions and height will be the corresponding values Constraints: * 1 <= heights.length <= 10^5 * 0 <= heights[i] <= 10^4 1.Bruteforce: *we can start from every possible recatngles that can be formed from the given array *with respect to width we can make upto n^2 possible *while considering the height choose the rectangle with less height Implementation: maxRectangleArea for i in n: for j in n: maxRectangleArea = max(maxRectangleArea, (j-i+1) * min(arr[i],arr[j]) ) Analysis: Time Complexity: O(n^2) Space Complexity: O(1) 2. presum: Idea: bruteforcs can be written as for each index: maxarea = max(height[index]*(leftindex[i] - rightindex[i])) with precached the leftsmallest index and right smallest index we can optmize the bruteforce method for leftsmallest index move until we hit the smallest height similary for right smallest index repeat the process Analysis: Time Complexity: O(n) Space Complexity: O(n) 3. stacks: in presum technique we only cache the information of bars in increaing heights instead of using two separate arrays to store it's value we can use a stack of bars we identified so far with only bars greater than current bar Analysis: Time Complexity: O(n) Space Complexity: O(n) """ def largestRectangleArea(self, heights: List[int]) -> int: return self.stack(heights) def bruteforce(self, heights: List[int]) -> int: n = len(heights) maxRec = float("-INF") for i in range(n): curHeight = heights[i] for j in range(i, n): curHeight = min(curHeight, heights[j]) maxRec = max(maxRec, abs(j - i + 1) * curHeight) return maxRec def presum(self, heights: List[int]) -> int: n = len(heights) left = [0] * n right = [0] * n left[0] = -1 right[n - 1] = n for i in range(1, n): curr = i - 1 while curr >= 0 and heights[i] <= heights[curr]: curr = left[curr] left[i] = curr for i in range(n - 2, -1, -1): curr = i + 1 while curr <= n - 1 and heights[i] <= heights[curr]: curr = right[curr] right[i] = curr maxRec = float("-INF") for i in range(n): maxRec = max(maxRec, heights[i] * (right[i] - left[i] - 1)) return maxRec def stack(self, heights: List[int]) -> int: heights.append(0) stack = [] maxRec = 0 n = len(heights) for i in range(n): height = heights[i] while stack and heights[stack[-1]] >= height: H = heights[stack.pop()] W = i if not stack else i - stack[-1] - 1 maxRec = max(maxRec, H * W) stack.append(i) return maxRec ```