-
Notifications
You must be signed in to change notification settings - Fork 0
/
084_LargestRectangleInHistogram84.java
134 lines (117 loc) · 4.26 KB
/
084_LargestRectangleInHistogram84.java
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/**
* Given n non-negative integers representing the histogram's bar height where
* the width of each bar is 1, find the area of largest rectangle in the histogram.
*
* https://leetcode.com/static/images/problemset/histogram.png
* Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].
*
* https://leetcode.com/static/images/problemset/histogram_area.png
* The largest rectangle is shown in the shaded area, which has area = 10 unit.
*
* For example,
* Given heights = [2,1,5,6,2,3],
* return 10.
*
*/
public class LargestRectangleInHistogram84 {
/**
* https://discuss.leetcode.com/topic/7599/o-n-stack-based-java-solution
*/
public int largestRectangleArea(int[] height) {
int len = height.length;
Stack<Integer> s = new Stack<Integer>();
int maxArea = 0;
for(int i = 0; i <= len; i++){
int h = (i == len ? 0 : height[i]);
if(s.isEmpty() || h >= height[s.peek()]){
s.push(i);
}else{
int tp = s.pop();
maxArea = Math.max(maxArea, height[tp] * (s.isEmpty() ? i : i - 1 - s.peek()));
i--;
}
}
return maxArea;
}
/**
* https://discuss.leetcode.com/topic/39151/5ms-o-n-java-solution-explained-beats-96
*/
public int largestRectangleArea2(int[] height) {
if (height == null || height.length == 0) {
return 0;
}
int[] lessFromLeft = new int[height.length]; // idx of the first bar the left that is lower than current
int[] lessFromRight = new int[height.length]; // idx of the first bar the right that is lower than current
lessFromRight[height.length - 1] = height.length;
lessFromLeft[0] = -1;
for (int i = 1; i < height.length; i++) {
int p = i - 1;
while (p >= 0 && height[p] >= height[i]) {
p = lessFromLeft[p];
}
lessFromLeft[i] = p;
}
for (int i = height.length - 2; i >= 0; i--) {
int p = i + 1;
while (p < height.length && height[p] >= height[i]) {
p = lessFromRight[p];
}
lessFromRight[i] = p;
}
int maxArea = 0;
for (int i = 0; i < height.length; i++) {
maxArea = Math.max(maxArea, height[i] * (lessFromRight[i] - lessFromLeft[i] - 1));
}
return maxArea;
}
/**
* https://discuss.leetcode.com/topic/2424/my-modified-answer-from-geeksforgeeks-in-java
*/
public int largestRectangleArea3(int[] height) {
if (height==null) return 0;//Should throw exception
if (height.length==0) return 0;
Stack<Integer> index= new Stack<Integer>();
index.push(-1);
int max=0;
for (int i=0;i<height.length;i++){
//Start calculate the max value
while (index.peek()>-1)
if (height[index.peek()]>height[i]){
int top=index.pop();
max=Math.max(max,height[top]*(i-1-index.peek()));
}else break;
index.push(i);
}
while(index.peek()!=-1){
int top=index.pop();
max=Math.max(max,height[top]*(height.length-1-index.peek()));
}
return max;
}
/**
* https://discuss.leetcode.com/topic/39836/share-my-2ms-java-solution-beats-100-java-submissions
*/
public int largestRectangleArea4(int[] heights) {
if (heights == null || heights.length == 0) return 0;
return getMax(heights, 0, heights.length);
}
private int getMax(int[] heights, int s, int e) {
if (s + 1 >= e) return heights[s];
int min = s;
boolean sorted = true;
for (int i = s; i < e; i++) {
if (i > s && heights[i] < heights[i - 1]) sorted = false;
if (heights[min] > heights[i]) min = i;
}
if (sorted) {
int max = 0;
for (int i = s; i < e; i++) {
max = Math.max(max, heights[i] * (e - i));
}
return max;
}
int left = (min > s) ? getMax(heights, s, min) : 0;
int right = (min < e - 1) ? getMax(heights, min + 1, e) : 0;
return Math.max(Math.max(left, right), (e - s) * heights[min]);
}
}