LeetCode303、84、85

今日份算法题,就都写在一起吧。

LeetCode:303区域和检索 - 数组不可变

题目 

给定一个整数数组  nums,求出数组从索引 到 j  (i ≤ j) 范围内元素的总和,包含 i,  j 两点。

示例:

给定 nums = [-2, 0, 3, -5, 2, -1],求和函数为 sumRange()

sumRange(0, 2) -> 1
sumRange(2, 5) -> -1
sumRange(0, 5) -> -3

说明:

  1. 你可以假设数组不可变。
  2. 会多次调用 sumRange 方法。

 大量的调用sumRange方法,那最直接的求和方式一定是会超时的,方法也很简单,遍历数组的同时,计算出当前的数字累加和,存放到sumArray数组中,当调用sumRange方法时,只需要计算 sumArray[j] - sumArray[i] + nums[i]  或者是 sumArray[j[ - sumArray[i-1] 即可。

代码

class NumArray {
    
    static int[] sumArray ;
    static int[] array;
    public NumArray(int[] nums) {
        sumArray = new int[nums.length];
        array = new int[nums.length];
        for (int i = 0; i < nums.length; i++) {
            array[i] = nums[i];
            if (i == 0) sumArray[i] = nums[i];
            else sumArray[i] = nums[i] + sumArray[i-1];
        }
    }
    
    public int sumRange(int i, int j) {
        return  sumArray[j] - sumArray[i] + array[i];
    }
}

/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray obj = new NumArray(nums);
 * int param_1 = obj.sumRange(i,j);
 */

 LeetCode:84. 柱状图中最大的矩形

题目

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]

图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。

示例:

输入: [2,1,5,6,2,3]
输出: 10

这道题是看了解题报告之后做的。

当我们的柱形图中的柱子是按照升序排列,及 4,5,6,7,8 ,那么最大面积比较容易算得 :也就是  4*4    5*3    6*2    8*1 中的最大数16。

可题目中的数据不一定会是升序排列的,那我们就要想办法将它排列成升序,这里就用到了栈,来维护一个升序柱状图,当某个柱子想要入栈,那么需要判断该柱高和栈顶的大小,如果大于栈顶数,那么该柱子直接入栈;那如果是小于栈顶,栈顶就需要出栈,出栈的同时计算一下该柱子的面积,出栈直到栈顶小于该柱高,柱子进栈,出栈了的柱子同时也将柱高变成和刚刚的柱子一样的高,重新入栈。

2  1   5  6   2   3      maxArea = 0

此时栈为空          2 可以直接入栈    ,  此时栈: 2 

此时栈顶为2        1   与栈顶2比较  1 < 2 , 栈顶出栈  maxArea = 2 * 1=2,  1 入栈   2变为1  入栈    此时栈:1   1

此时栈顶为1         5  与栈顶1比较  5 > 1 , 可以入栈,  此时栈: 1   1   5

此时栈顶为5         6  与栈顶1比较  6 > 5 , 可以入栈,  此时栈: 1   1   5     6

此时栈顶为6         2  与栈顶1比较  2 < 6 ,  栈顶出栈  maxArea = max(2 , 6 * 1 ) = 6,

此时栈顶为5         同样2<5 需要出栈, maxArear = max  (6, 5*2) = 10 (这里的5 * 2 : 5是柱子的高  2是出栈了的两个柱子)

此时栈顶为1         现在2 > 1 可以入栈了, 连通前两个出栈的5 6 都变为 2  一起入栈,现在的栈: 1  1  2  2  2

此时栈顶为2         现在3 > 2 可以入栈, 此时栈 1  1  2  2  2  3

现在的maxArea = 10;

现在栈中是一个升序的柱状图了,可以暗账上面所说的来进行计算 1*6  1*5  2*4  2*3  2*2  3*1 最大数为8 但是8 < 10 所以maxArea还是10

代码

class Solution {
    public int largestRectangleArea(int[] heights) {
        Stack<Integer> stack = new Stack();

        int result = 0;

        for (int i = 0; i < heights.length; i++) {

            if (stack.isEmpty() || stack.peek() < heights[i]){
                stack.push(heights[i]);
                continue;
            }

            int count = 0;
            int temp = stack.peek();
            while (temp > heights[i]){
                stack.pop();
                result = Math.max(result,temp * ++count);
                if (stack.isEmpty()) break;
                temp = stack.peek();
            }
            while (count-- >= 0) {
                stack.push(heights[i]);
            }
        }

        System.out.println(stack);

        int count = 0;
        while (!stack.isEmpty()){
             result = Math.max(result,stack.pop() * ++count);
        }

        return result;
    }
}

LeetCode:85. 最大矩形

题目

给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

示例:

输入:
[
  ["1","0","1","0","0"],
  ["1","0","1","1","1"],
  ["1","1","1","1","1"],
  ["1","0","0","1","0"]
]
输出: 6

这个题和上面的题时有些联系的,这个题可以看为上面的题的扩展,可以把这个二维数组想像成多个柱形图,按照上面的输入样例为例,可以看为4个柱形图,第一行为底,第二行为底,第三行为底,第四行为底,4个,然后用上面84题的解法来解。

代码

class Solution {
    public static int maximalRectangle(char[][] matrix) {
        if (matrix.length == 0 )return 0;
        int result = 0;
        int[][] nums = new int[matrix.length][matrix[0].length];
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                if (i == 0 && matrix[i][j] == '1'){
                    nums[i][j] = 1;
                }else if (matrix[i][j] == '1'){
                    nums[i][j] = nums[i-1][j] + 1;
                }
            }
            result = Math.max(result,maxArea(nums[i]));
        }
        return result;

    }

    public static int maxArea (int[] heights){

        Stack<Integer> stack = new Stack();

        int result = 0;

        for (int i = 0; i < heights.length; i++) {

            if (stack.isEmpty() || stack.peek() < heights[i]){
                stack.push(heights[i]);
                continue;
            }

            int count = 0;
            int temp = stack.peek();
            while (temp > heights[i]){
                stack.pop();
                result = Math.max(result,temp * ++count);
                if (stack.isEmpty()) break;
                temp = stack.peek();
            }
            while (count-- >= 0)
                stack.push(heights[i]);
        }


        int count = 0;
        while (!stack.isEmpty())
             result = Math.max(result,stack.pop() * ++count);


        return result;
    }
    
}

猜你喜欢

转载自blog.csdn.net/qq_38595487/article/details/81807659