Tuesday, March 12, 2024

 

Question: Find the maximum rectangle enclosed by the following barchart: 

                                       ____ 

12 |                               |      | 

10 |                               |      | 

  8 |           ___              |      |----- 

  6 |   ___|     |      ___|              |___ 

  4 |  |    |       |__|                              |____________ 

  2 |  |    |             |                                                           | 

  0  -------------------------------------------------------------------------- 

Solution: public class Main { 

    public static void main(String[] args) throws Exception { 

        List<Integer> A = Arrays.asList(4, 6, 2, 4, 12, 7, 4,2,2,2); 

        System.out.println(getMaxRectangleStreaming(A)); 

    } 

    public static int getMaxRectangleStreaming(List<Integer> A) { 

        int maxArea = Integer.MIN_VALUE; 

        int maxHeight = Integer.MIN_VALUE; 

        List<Integer> heights = new ArrayList<>(); 

        // parallel sums of unit-areas of bounding boxes with top-left at incremental heights of the current bar in a barchart 

        List<Integer> areas = new ArrayList<>(); 

        int prev = 0; 

        for (int i = 0; i < A.size(); i++) { 

            if (A.get(i) > maxHeight) { 

                maxHeight = A.get(i); 

            } 

            if (prev < A.get(i)) { 

                for (int j = 0; j < A.get(i); j++) { 

                    if (heights.size() < j+1) heights.add(0); 

                    if (areas.size() < j+1) areas.add(0); 

                    heights.set(j, (j+1) * 1); 

                    if ( j < areas.size()) { 

                        int newArea = areas.get(j) + (j + 1) * 1; 

                        areas.set(j, newArea); 

                        if (newArea > maxArea) { 

                            maxArea = newArea; 

                        } 

                    } else { 

                        areas.set(j, (j+1) * 1); 

                    } 

                } 

            } else { 

                for (int j = 0; j < A.get(i); j++) { 

                    heights.set(j, (j+1) *1); 

                    if ( j < areas.size()) { 

                        int newArea = areas.get(j) + (j + 1) * 1; 

                        areas.set(j, newArea); 

                        if (newArea > maxArea) { 

                            maxArea = newArea; 

                        } 

                    } else { 

                        areas.set(j, (j+1) * 1); 

                    } 

                } 

                for (int j = A.get(i); j < prev; j++){ 

                    heights.set(j, 0); 

                    if (areas.size() > j && areas.get(j) > maxArea) { 

                        maxArea = areas.get(j); 

                    } 

                    areas.set(j, 0); 

                } 

            } 

            prev = A.get(i); 

            System.out.println("heights:" + print(heights)); 

            System.out.println("areas:" + print(areas)); 

        } 

        return maxArea; 

    } 

    public static String print(List<Integer> A){ 

        StringBuilder sb = new StringBuilder(); 

        for (Integer a : A) { 

            sb.append(a + " "); 

        } 

        return sb.toString(); 

    }; 

 

//Output: 

heights:1 2 3 4  

areas:1 2 3 4  

heights:1 2 3 4 5 6  

areas:2 4 6 8 5 6  

heights:1 2 0 0 0 0  

areas:3 6 0 0 0 0  

heights:1 2 3 4 0 0  

areas:4 8 3 4 0 0  

heights:1 2 3 4 5 6 7 8 9 10 11 12  

areas:5 10 6 8 5 6 7 8 9 10 11 12  

heights:1 2 3 4 5 6 7 0 0 0 0 0  

areas:6 12 9 12 10 12 14 0 0 0 0 0  

heights:1 2 3 4 0 0 0 0 0 0 0 0  

areas:7 14 12 16 0 0 0 0 0 0 0 0  

heights:1 2 0 0 0 0 0 0 0 0 0 0  

areas:8 16 0 0 0 0 0 0 0 0 0 0  

heights:1 2 0 0 0 0 0 0 0 0 0 0  

areas:9 18 0 0 0 0 0 0 0 0 0 0  

heights:1 2 0 0 0 0 0 0 0 0 0 0  

areas:10 20 0 0 0 0 0 0 0 0 0 0  

20 

 

 

No comments:

Post a Comment