-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMaxRectangle.java
137 lines (119 loc) · 3.32 KB
/
MaxRectangle.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
135
136
137
package Stack;
public class MaxRectangle {
public static int[] nextsmallerelement(int[] arr, int n)
{
Stack<Integer> st = new Stack<>();
// For the elements which dont have
// next smaller element ans will be -1
st.push(-1);
// Store indices in output
int[] right = new int[n];
// Start from last index
for (int i = n - 1; i >= 0; i--) {
// If top element is sorted then
// no need to do anything, just store
// the answer and push the
// current element in stack
if ((st.peek() != -1)
&& arr[st.peek()] < arr[i]) {
right[i] = st.peek();
st.push(i);
}
else {
while ((st.peek() != -1)
&& arr[st.peek()]
>= arr[i]) {
st.pop();
}
right[i] = st.peek();
st.push(i);
}
}
return right;
}
public static int[] previousmallerelement(int arr[],int n)
{
Stack<Integer> st = new Stack<>();
st.push(-1);
int[] left = new int[n];
// Start from first index - Difference Between Next and Previous Smaller element
for (int i = 0; i < n; i++) {
if ((st.peek() != -1)
&& arr[st.peek()] < arr[i]) {
left[i] = st.peek();
st.push(i);
}
else {
while ((st.peek() != -1)
&& arr[st.peek()]
>= arr[i]) {
st.pop();
}
left[i] = st.peek();
st.push(i);
}
}
return left;
}
public static int getMaxArea(int [] arr, int n)
{
int [] right = new int [n];
right = nextsmallerelement(arr, n);
// Find the smallest element than
// curr element in right side
int [] left = new int [n];
left = previousmallerelement(arr, n);
// Find the smallest element
// than curr element in left side
int maxarea = Integer.MIN_VALUE;
// Now the left and right array have
// index of smallest element in left and
// right respectively, thus the difference
// of right - left - 1 will give us
// breadth and thus
// area = height(curr==arr[i]) * breadth;
for (int i = 0; i < n; i++) {
int height = arr[i];
if (right[i] == -1) {
right[i] = n;
}
int breadth = right[i] - left[i] - 1;
maxarea = Math.max(maxarea,
height * breadth);
}
return maxarea;
}
public static int maxRectangleArea(int [][] M, int R, int C)
{
int area = getMaxArea(M[0], R);
int maxarea = area;
for (int i = 1; i < R; i++) {
for (int j = 0; j < C; j++) {
if (M[i][j] != 0) {
// Add heights of previous rows
// into current
M[i][j] = M[i][j]
+ M[i - 1][j];
}
else {
// If current height is 0 then
// don't add previous heights
M[i][j] = 0;
}
}
maxarea = Math.max(maxarea,
getMaxArea(M[i], R));
}
return maxarea;
}
public static void main(String[] args) {
int R = 4, C = 4;
int [][]amt = {
{ 0, 1, 1, 0 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 0, 0 },
};
System.out.println(maxRectangleArea(amt, R, C));
}
}