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
}
}