85. 最大矩形

链接

题目.

难度:

high

解答:

这道题最难的就是想到要用柱状图的最大矩形面积来计算,从而把复杂度降低到n*n

package main

import "fmt"

func largestRectangleArea(heights []int) int {
	if len(heights) == 0 {
		return 0
	}

	if len(heights) == 1 {
		return heights[0]
	}

	results := make([]int, len(heights))
	copy(results, heights)

	asc := make([]int, 0, len(heights))
	asc = append(asc, 0)
	for i := 1; i < len(heights); i++ {
		if heights[asc[0]] >= heights[i] {
			asc = asc[:1]
			asc[0] = i
			results[i] += heights[i] * i
		}

		for j := len(asc) - 1; j >= 0; j-- {
			if heights[asc[j]] < heights[i] {
				results[i] += heights[i] * (i - asc[j] - 1)
				asc = asc[:j+1]
				break
			}
		}

		asc = append(asc, i)
	}

	asc = asc[:1]
	asc[0] = len(heights) - 1
	for i := len(heights) - 2; i >= 0; i-- {
		if heights[asc[0]] >= heights[i] {
			asc = asc[:1]
			asc[0] = i
			results[i] += heights[i] * (len(heights) - 1 - i)
		}

		for j := len(asc) - 1; j >= 0; j-- {
			if heights[asc[j]] < heights[i] {
				results[i] += heights[i] * (asc[j] - 1 - i)
				asc = asc[:j+1]
				break
			}
		}

		asc = append(asc, i)
	}

	max := 0
	for _, v := range results {
		if v > max {
			max = v
		}
	}

	return max
}

func maximalRectangle(matrix [][]byte) int {
	if len(matrix) == 0 || len(matrix[0]) == 0 {
		return 0
	}

	maxRec := 0
	areaVec := make([]int, len(matrix[0]))
	for i := 0; i < len(matrix); i++ {
		for j := 0; j < len(matrix[i]); j++ {
			if matrix[i][j] == '0' {
				areaVec[j] = 0
			} else {
				areaVec[j]++
			}
		}
		if res := largestRectangleArea(areaVec); res > maxRec {
			maxRec = res
		}
	}

	return maxRec
}

func main() {
	matrix := [][]byte{
		{'1', '0', '1', '0', '0'},
		{'1', '0', '1', '1', '1'},
		{'1', '1', '1', '1', '1'},
		{'1', '0', '0', '1', '0'},
	}
	fmt.Println(maximalRectangle(matrix))
}

复杂度分析

time

O(n*n)

space

O(n)

执行结果

执行用时 :
0 ms
, 在所有 Go 提交中击败了
100.00%
的用户
内存消耗 :
5.2 MB
, 在所有 Go 提交中击败了
60.00%
的用户

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值