算法学习

算法题--求最大矩形面积

2020-04-24  本文已影响0人  岁月如歌2020
image.png

0. 链接

题目链接

1. 题目

Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.

示意图

Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].

示意图

The largest rectangle is shown in the shaded area, which has area = 10 unit.

Example:

Input: [2,1,5,6,2,3]
Output: 10

2. 思路1:尝试以每个位置作为矩形的高, 再找到宽, 然后求出最大面积

3. 代码

# coding:utf8
from typing import List


class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        n = len(heights)
        min_values = [[0] * n for _ in range(n)]
        dp = [[0] * n for _ in range(n)]
        max_value = 0
        for i in range(n):
            for j in range(i, n):
                if j > i:
                    min_values[i][j] = min(min_values[i][j - 1], heights[j])
                else:
                    min_values[i][i] = heights[i]
                dp[i][j] = min_values[i][j] * (j - i + 1)
                max_value = max(max_value, dp[i][j])

        return max_value


class Solution1:
    def largestRectangleArea(self, heights: List[int]) -> int:
        n = len(heights)
        if n == 0:
            return 0

        less_from_left = [None] * n     # 每个元素往左数第一个小于该元素的位置
        less_from_right = [None] * n    # 每个元素往右数第一个小于该元素的位置
        less_from_left[0] = -1          # 特殊位置特殊处理, 方便后面计算宽度
        less_from_right[n - 1] = n      # 特殊位置特殊处理, 方便后面计算宽度

        for i in range(1, n):
            p = i - 1
            while p >= 0 and heights[p] >= heights[i]:
                p = less_from_left[p]   # 继续往左找第一个比heights[p]更小的元素
            less_from_left[i] = p       # 找到了i左边第一个比heights[i]更小的元素, 记录下来留给其他的i使用

        for i in range(n - 2, -1, -1):
            p = i + 1
            while p < n and heights[p] >= heights[i]:
                p = less_from_right[p]  # 继续往右边找第一个比heights[p]更小的元素
            less_from_right[i] = p      # 找到了i右边第一个比heights[i]更小的元素, 记录下来留给其他的i使用

        max_val = 0
        for i in range(n):
            # 计算以每个位置为高的矩形面积, 遴选出最大面积
            max_val = max(max_val, heights[i] * (less_from_right[i] - less_from_left[i] - 1))

        return max_val


def my_test(solution, heights):
    print('input: {}, output: {}'.format(heights, solution.largestRectangleArea(heights)))


solution = Solution1()
my_test(solution, [2, 1, 5, 6, 2, 3])
my_test(solution, [])

输出结果

input: [2, 1, 5, 6, 2, 3], output: 10
input: [], output: 0

4. 结果

image.png
上一篇 下一篇

猜你喜欢

热点阅读