Skip to content

Commit f8a51ba

Browse files
committed
Max rectangle of 1s: done
1 parent 6682be2 commit f8a51ba

File tree

4 files changed

+163
-8
lines changed

4 files changed

+163
-8
lines changed

src/main/java/com/rampatra/dynamicprogramming/FibonacciNumbers.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
public class FibonacciNumbers {
1414

1515
/**
16-
* Computes first {@param k} fibonacci numbers using
16+
* Computes first {@code k} fibonacci numbers using
1717
* bottom-up DP approach.
1818
* <p/>
1919
* Time complexity: O(k)

src/main/java/com/rampatra/dynamicprogramming/LongestIncreasingSubSequence.java

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
package com.rampatra.dynamicprogramming;
22

33
/**
4-
* Created by IntelliJ IDEA.
5-
*
64
* @author rampatra
75
* @since 9/29/15
8-
* @time: 10:15 PM
96
*/
107
public class LongestIncreasingSubSequence {
118

@@ -26,11 +23,11 @@ public class LongestIncreasingSubSequence {
2623
* To get LIS of a given array, we need to return max(L(i)) where 0 < i < n So the LIS problem has optimal
2724
* substructure property as the main problem can be solved using solutions to sub-problems.
2825
*
29-
* @param a
26+
* @param arr
3027
* @return
3128
*/
32-
public static int getLongestIncreasingSubSequenceLength(int[] a) {
33-
int len = a.length, maxLisLength = 0;
29+
public static int getLongestIncreasingSubSequenceLength(int[] arr) {
30+
int len = arr.length, maxLisLength = 0;
3431
int[] lis = new int[len];
3532

3633
for (int i = 0; i < len; i++) {
@@ -39,7 +36,7 @@ public static int getLongestIncreasingSubSequenceLength(int[] a) {
3936

4037
for (int i = 1; i < len; i++) {
4138
for (int j = 0; j < i; j++) {
42-
if (a[i] > a[j] && lis[i] < lis[j] + 1)
39+
if (arr[i] > arr[j] && lis[i] < lis[j] + 1)
4340
lis[i] = lis[j] + 1;
4441
}
4542
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.rampatra.dynamicprogramming;
2+
3+
import com.rampatra.stacks.MaxRectangleAreaInHistogram;
4+
5+
/**
6+
* Given a 2D matrix of 0s and 1s. Find the largest rectangle of all 1s in this matrix.
7+
* <p>
8+
* Level: Hard
9+
* Time Complexity: O(rows * cols)
10+
* Space Complexity: O(cols)
11+
* <p>
12+
* Note: If the number of cols is too large as compared to rows then you can process the matrix column-wise and create
13+
* the histogram for each column. In this way the hist[] array will be of size = number of rows in the matrix.
14+
*
15+
* @author rampatra
16+
* @since 2019-04-05
17+
*/
18+
public class MaximumRectangleOf1sInMatrix {
19+
20+
private static int getMaxRectangleSizeOf1s(int[][] binaryMatrix) {
21+
int area;
22+
int maxArea = 0;
23+
int[] hist = new int[binaryMatrix[0].length];
24+
25+
/*
26+
Create a histogram with the rows. Start with the first row, create a histogram and then extend this
27+
histogram based on the elements in the next rows. If the element in the row is a 0 then make the bar in
28+
the histogram 0 or else just increase the bar in the histogram.
29+
30+
Basically, we are creating a histogram with all the 1s in the matrix and then finding the maximum
31+
rectangle size of this histogram.
32+
*/
33+
for (int row = 0; row < binaryMatrix.length; row++) {
34+
for (int col = 0; col < binaryMatrix[0].length; col++) {
35+
if (binaryMatrix[row][col] == 0) {
36+
hist[col] = 0;
37+
} else {
38+
hist[col] += binaryMatrix[row][col];
39+
}
40+
}
41+
area = MaxRectangleAreaInHistogram.getMaxRectangleArea(hist);
42+
maxArea = Math.max(maxArea, area);
43+
}
44+
return maxArea;
45+
}
46+
47+
public static void main(String[] args) {
48+
System.out.println(getMaxRectangleSizeOf1s(
49+
new int[][]{{0, 1, 1},
50+
{0, 0, 1},
51+
{0, 1, 1}}));
52+
53+
System.out.println(getMaxRectangleSizeOf1s(
54+
new int[][]{{0, 1, 1, 1, 0},
55+
{0, 0, 1, 1, 0},
56+
{0, 1, 1, 1, 0}}));
57+
58+
System.out.println(getMaxRectangleSizeOf1s(
59+
new int[][]{{1, 1, 1, 0},
60+
{1, 1, 1, 1},
61+
{0, 1, 1, 0},
62+
{0, 1, 1, 1},
63+
{1, 0, 0, 1},
64+
{1, 1, 1, 1}}));
65+
66+
// edge cases
67+
System.out.println(getMaxRectangleSizeOf1s(
68+
new int[][]{{}}));
69+
70+
System.out.println(getMaxRectangleSizeOf1s(
71+
new int[][]{{0}}));
72+
73+
System.out.println(getMaxRectangleSizeOf1s(
74+
new int[][]{{0, 0, 0}}));
75+
76+
System.out.println(getMaxRectangleSizeOf1s(
77+
new int[][]{{1}}));
78+
}
79+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.rampatra.stacks;
2+
3+
/**
4+
* Given a bar histogram, calculate the maximum possible rectangle area in the histogram. Consider each bar is 1 unit
5+
* wide.
6+
* <p>
7+
* Level: Hard
8+
* Time Complexity: O(n)
9+
* Space Complexity: O(n)
10+
*
11+
* @author rampatra
12+
* @since 2019-04-04
13+
*/
14+
public class MaxRectangleAreaInHistogram {
15+
16+
public static int getMaxRectangleArea(int[] hist) {
17+
Stack<Integer> stack = new Stack<>();
18+
int area;
19+
int maxArea = 0;
20+
int currMaxIndex;
21+
int i = 0;
22+
23+
while (i < hist.length) {
24+
// keep adding indexes of bars which are equal to or larger than what's there in stack currently
25+
if (stack.isEmpty() || hist[i] >= hist[stack.peek()]) {
26+
stack.push(i);
27+
i++;
28+
} else {
29+
/*
30+
Whenever we encounter a bar smaller than what is there in the stack, we pop the topmost
31+
element and compute the area.
32+
*/
33+
currMaxIndex = stack.pop();
34+
/*
35+
Compute area from stack.peek() to (i - 1),
36+
37+
Why (i - 1)? Because i has been incremented and is now pointing to the next bar in the
38+
histogram
39+
40+
Why stack.peak()? Because hist[stack.peek() + 1] is the last bar in the histogram with height more
41+
than or equal to the current bar height
42+
*/
43+
area = hist[currMaxIndex] * (i - (stack.isEmpty() ? 0 : stack.peek() + 1));
44+
maxArea = Math.max(maxArea, area);
45+
}
46+
}
47+
48+
/*
49+
Process the left over elements in the stack. Note: the below code can also be merged with the loop
50+
above but I have separated it out for simplicity.
51+
*/
52+
while (!stack.isEmpty()) {
53+
currMaxIndex = stack.pop();
54+
area = hist[currMaxIndex] * (i - (stack.isEmpty() ? 0 : stack.peek() + 1));
55+
maxArea = Math.max(maxArea, area);
56+
}
57+
58+
return maxArea;
59+
}
60+
61+
public static void main(String[] args) {
62+
/*
63+
___
64+
___ | | ___
65+
| |__| |__| |
66+
| | | | | |
67+
2 1 3 1 2
68+
69+
Max. area in this histogram is 5, which is the bottom horizontal rectangle.
70+
*/
71+
System.out.println(getMaxRectangleArea(new int[]{2, 1, 3, 1, 2})); // maxArea = 5
72+
System.out.println(getMaxRectangleArea(new int[]{2, 1, 5, 6, 2, 3})); // maxArea = 10
73+
System.out.println(getMaxRectangleArea(new int[]{2, 2, 2, 6, 1, 5, 4, 2, 2, 2, 2})); // maxArea = 12
74+
75+
// edge cases
76+
System.out.println(getMaxRectangleArea(new int[]{})); // maxArea = 0
77+
System.out.println(getMaxRectangleArea(new int[]{1})); // maxArea = 1
78+
}
79+
}

0 commit comments

Comments
 (0)