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
    }    
}
posted @ 2020-07-27 18:09  ganshuoos  阅读(120)  评论(0编辑  收藏  举报