zoukankan      html  css  js  c++  java
  • leetcode刷题笔记八十五题 最大矩形

    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

    /**
    本题主要讨论两种解法,第一种方法基于84题柱状图的单调栈解法结合动态规划
    将矩阵中的每一行作为一次x轴,对其中以该点能达到的最大高度视为柱状图高度处理即可
    时间复杂度:O(mn)
    空间复杂度:O(n)
    */
    import scala.collection.mutable
    object Solution {
        def maximalRectangle(matrix: Array[Array[Char]]): Int = {
            val rowLength = matrix.length
            if (rowLength == 0) return 0
            val colLength = matrix(0).length
            val dp = Array.fill(colLength)(0)
            var max = 0
    
            for(i <- 0 to rowLength-1){
                for(j <- 0 to colLength-1){
                    if(matrix(i)(j) == '1')   dp(j) += 1
                    else dp(j) = 0
                }
                //println(dp.mkString(" "))
                max = Math.max(max, largestRectangleArea(dp))
            }
            return max
        }
    
        def largestRectangleArea(heights: Array[Int]): Int = {
            val newHeights = Array(0).concat(heights).concat(Array(0))
            val length = newHeights.length
            val stack = new mutable.Stack[Int]()
            var area = 0
            stack.push(0)
    
            for(i <- 1 to length-1){
                while(newHeights(stack.top) > newHeights(i)){
                    val height = newHeights(stack.pop)
                    val width  = i - stack.top - 1
                    area = Math.max(area, height*width) 
                }
                stack.push(i)
            }
            return area
        }
    }
    
    /**
    法二是基于动态规划思想,使用heigth、left和right三个数组以行为单位计录该行中当前元素能够成矩阵的最大高度,最左侧及最右侧,用于计算矩阵面积。
    */
    import scala.collection.mutable
    object Solution {
        def maximalRectangle(matrix: Array[Array[Char]]): Int = {
            val rowLength = matrix.length
            if (rowLength == 0) return 0
            val colLength = matrix(0).length
            val height = Array.fill(colLength)(0)
            val left = Array.fill(colLength)(0)
            val right = Array.fill(colLength)(colLength)
            var area = 0
    
            for(i <- 0 to rowLength-1){
                var curLeft  = 0
                var curRight = colLength
    
                //height
                for(j <- 0 to colLength-1){
                    if(matrix(i)(j) == '1') height(j) += 1
                    else height(j) = 0
                }
    
                //left
                for(j <- 0 to colLength-1){
                    if(matrix(i)(j) == '1') left(j) = Math.max(left(j), curLeft)
                    else{
                        //left(j)设置为0,不影响面积计算,即height == 0
    					//设置为0 不影响后续max计算
                        left(j) = 0
                        curLeft = j + 1
                    }
                }
    
                //right
                for(j <- (0 to colLength-1).reverse){
                    if(matrix(i)(j) == '1') right(j) = Math.min(right(j), curRight)
                    else{
                         //right(j)设置为colLength,不影响面积计算,即height == 0
    					//设置为colLength 不影响后续min计算
                        right(j) = colLength
                        curRight = j
                    }
                }
    
                //area
                for(j <- 0 to colLength-1) area = Math.max(area, height(j)*(right(j) - left(j)))
            }
            return area
        }    
    }
    
  • 相关阅读:
    7种jvm垃圾回收器,这次全部搞懂
    3分钟学会redis主从复制搭建,及原理
    一文搞懂什么是递归,程序员必会算法之一
    Redis持久化方式:RDB和AOF详解,对比
    jvm垃圾回收算法详解,看这一篇就够了(求点赞)
    Redis命令大全,满足你的日常工作,看这一篇就够了(求点赞)
    Java自定义异常为什么性能差(求点赞)阿里双十一的性能凶手之一
    jvm类加载器,类加载机制详解,看这一篇就够了(求点赞)
    show processlist 命令详解,MySQL优化看这一篇就够了
    asp.net中的post和get请求操作
  • 原文地址:https://www.cnblogs.com/ganshuoos/p/13386840.html
Copyright © 2011-2022 走看看