zoukankan      html  css  js  c++  java
  • 【LEETCODE】63、数组分类,hard级别,题目:85、4、84

    package y2019.Algorithm.array.hard;
    
    /**
     * @ProjectName: cutter-point
     * @Package: y2019.Algorithm.array.hard
     * @ClassName: MaximalRectangle
     * @Author: xiaof
     * @Description: TODO 85. Maximal Rectangle
     * Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.
     *
     * Input:
     * [
     *   ["1","0","1","0","0"],
     *   ["1","0","1","1","1"],
     *   ["1","1","1","1","1"],
     *   ["1","0","0","1","0"]
     * ]
     * Output: 6
     *
     * 给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
     *
     * 如果是只包含的话,那么就需要计算面积
     *
     * @Date: 2019/7/26 16:54
     * @Version: 1.0
     */
    public class MaximalRectangle {
    
        public int solution(char[][] matrix){
            //这里就是一行不一行的遍历,然后通过每一行的数据的
            if(matrix == null || matrix.length <= 0) {
                return 0;
            }
    
            int rowLen = matrix.length;
            int colLen = matrix[0].length; //
    
            int left[] = new int[colLen], right[] = new int[colLen], height[] = new int[colLen];
    
            //初始化
            for(int j = 0; j < colLen; ++j) {
                right[j] = colLen;
            }
    
            //初始化right,用来标识这个直方图的右边坐标位置
            int maxA = 0; //最大面积
            for(int i = 0; i < rowLen; ++i) {
                int curLeft = 0, curRight = colLen;
                //循环遍历没一行
                for(int j = 0; j < colLen; ++j) {
                    if(matrix[i][j] == '1') {
                        //如果是1,那么就是++高度
                        height[j]++;
                    } else {
                        height[j] = 0;//否则这个直方图的高度目前为0
                    }
                }
    
                //计算左边坐标,从0开始,因为每当出现1的时候,我们就累加进去,如果没有出现1,是0,那么我们要把坐标起始位置向右边移动一位
                //如果是1,那么以最大值为准,因为上一层的为1 的低位在这一层为0,那么就断掉了,不再这个直方图中
                for(int j = 0; j < colLen; ++j) {
                    if(matrix[i][j] == '1') {
                        left[j] = Math.max(curLeft, left[j]);
                    } else {
                        //如果这个位置不是1,那么就要移动起始坐标
                        left[j] = 0;
                        curLeft = j + 1;
                    }
                }
    
                //计算直方图右边坐标,这个应该从1开始,计算右边一直在矩阵内的坐标
                for(int j = colLen - 1; j >= 0; --j) {
                    if(matrix[i][j] == '1') {
                        //这边取最小值,因为上一层有,这一层没有,那么就往左边缩
                        right[j] = Math.min(curRight, right[j]);
                    } else {
                        //如果这个位置不是1,那么就要移动起始坐标
                        right[j] = colLen;
                        curRight = j;
                    }
                }
    
                //计算最大面积
                for(int j = 0; j < colLen; ++j) {
                    maxA = Math.max(maxA, (right[j] - left[j]) * height[j]);
                }
    
            }
    
            return maxA;
    
        }
    
        public static void main(String args[]) {
            char data[][] = {{'1'}};
            char data2[][] = {
                    {'1','0','1','0','0'},
                    {'1','0','1','1','1'},
                    {'1','1','1','1','1'},
                    {'1','0','0','1','0'}
            };
            MaximalRectangle fuc = new MaximalRectangle();
            System.out.println(fuc.solution(data2));
        }
    
    }
    package y2019.Algorithm.array.hard;
    
    /**
     * @ClassName FindMedianSortedArrays
     * @Description TODO 4. Median of Two Sorted Arrays
     *
     * There are two sorted arrays nums1 and nums2 of size m and n respectively.
     * Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
     * You may assume nums1 and nums2 cannot be both empty.
     *
     * nums1 = [1, 3]
     * nums2 = [2]
     *
     * The median is 2.0
     *
     * 参考:https://www.youtube.com/watch?v=LPFhl65R7ww
     * @Author xiaof
     * @Date 2019/7/28 16:32
     * @Version 1.0
     **/
    public class FindMedianSortedArrays {
    
        public double solution(int[] nums1, int[] nums2) {
            if(nums1.length > nums2.length) {
                return solution(nums2, nums1); //我们需要根据长度小的中间位置计算另外一个长的位置的分割点
            }
    
            //获取总长
            int x = nums1.length;
            int y = nums2.length;
    
            //计算区间
            int low = 0, hight = x; //根据第一个数组进行分割
            while (low <= hight) {
                //只要瞒住条件,就一直循环,核心思想还是二分查找
                //开始分割
                int partitionx = (low +hight) / 2;
                int partitiony = (x + y + 1) / 2 - partitionx; //计算第二个数组的分割点,对于和是奇数的情况+1,可以向右边移动一位保证中间数据在左边,这样就不用判断左右了
    
                //计算两个数组中被分割的临近中间位置的数据,如果分割位置是0,那也就左边没有元素不用比较计算,直接设置最小值
                int maxLeftx = partitionx == 0 ? Integer.MIN_VALUE : nums1[partitionx - 1];
                int minRightx = partitionx == x ? Integer.MAX_VALUE : nums1[partitionx]; //右边最小位置
    
                int maxLefty = partitiony == 0 ? Integer.MIN_VALUE : nums2[partitiony - 1];
                int minRighty = partitiony == y ? Integer.MAX_VALUE : nums2[partitiony];
    
                //分三种情况,第一张找到了
                if(maxLeftx <= minRighty && maxLefty <= minRightx) {
                    //因为本身已经排好顺序,那么只要瞒住这个条件,那么就可以说这2个集合正好被分成了2块
                    //判断一共是奇数个还是偶数个
                    if((x + y) % 2 == 0) {
                        //偶数求平均值
                        return ((double) Math.max(maxLeftx, maxLefty) + Math.min(minRightx, minRighty)) / 2;
                    } else {
                        return (double) Math.max(maxLeftx, maxLefty);
                    }
                } else if (maxLeftx > minRighty) {
                    //如果左边的第一个序列的最大值比第二个序列右边最小值大,说明不是中分的数据,说明第一个序列分割的位置太大了,我们把这个元素划归到右边去
                    hight = partitionx - 1;
                } else {
                    //maxLefty 》 minRightx 右边第一个序列的最小值比下面的序列的最大值小,说明高位给低了
                    low = partitionx + 1;
                }
            }
    
            //最后出现异常情况,那就是如果序列没排序,那就GG
            return -1;
    
        }
    
        public static void main(String args[]) {
            int input1[] = {1,3};
            int input2[] = {2};
            FindMedianSortedArrays fuc = new FindMedianSortedArrays();
            System.out.println(fuc.solution(input1, input2));
        }
    
    }
    package y2019.Algorithm.array.hard;
    
    /**
     * @ClassName LargestRectangleArea
     * @Description TODO 84. Largest Rectangle in Histogram
     * 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.
     * @Author xiaof
     * @Date 2019/7/28 21:44
     * @Version 1.0
     **/
    public class LargestRectangleArea {
    
        public int solution(int[] heights) {
            if(heights == null || heights.length <= 0) {
                return 0;
            }
    
            //求最大面积,参考85. Maximal Rectangle ,可以用同样的思路求解
            //同样我们需要找到这个直方图的左边界,右边界,然后整合所有直方图的最大值
            int left[] = new int[heights.length], right[] = new int[heights.length];
    
            //遍历所有直方图,并根据当前直方图获取左右两边的位置 left
            left[0] = -1;
            for(int i = 1; i < heights.length; ++i) {
                int p = i - 1;
                while (p >= 0 && heights[p] >= heights[i]) {
    //                --p;
                    //这里不用每次都遍历,直接使用上次的结果就可以了
                    p = left[p];
                }
                //设置这个最左边的坐标
                left[i] = p;
            }
    
            //设置右边
            right[heights.length - 1] = heights.length;
            for(int i = heights.length - 2; i >= 0; --i) {
                int p = i + 1;
                while (p < heights.length && heights[p] >= heights[i]) {
    //                ++p;
                    //这里不用每次都遍历,直接使用上次的结果就可以了
                    p = right[p];
                }
                right[i] = p;
            }
    
            //求面积maxa = Math.max{maxa, heights[i] * (right[i] - left[i] - 1)}
            int maxa = 0;
            for(int i = 0; i < heights.length; ++i) {
                maxa = Math.max(maxa, heights[i] * (right[i] - left[i] - 1));
            }
    
            return maxa;
    
        }
    
        public static void main(String args[]) {
            int data[] = {2,1,5,6,2,3};
            LargestRectangleArea fuc = new LargestRectangleArea();
            System.out.println(fuc.solution(data));
        }
    
    }
  • 相关阅读:
    Lucence_Curd
    Lucence
    SpringMvc文件上传
    SpringMvc接收参数
    出现No qualifying bean of type [com.*.*.dao.InfoDao] found for :错误
    内连接、左外连接、右外连接、交叉连接区别
    html基础
    Java基础阶段综合练习
    java基础MySQL
    java基础IO删除文件夹文件
  • 原文地址:https://www.cnblogs.com/cutter-point/p/11262365.html
Copyright © 2011-2022 走看看