leetcode85.最大矩形

题目链接:https://leetcode.cn/problems/maximal-rectangle/

思路

将矩阵拆分成若干个柱状图,然后直接复用84.柱状图中最大的矩形的解法。

假设有以下矩阵:
leetcode85.最大矩形_第1张图片
矩阵前1行形成的柱状图:1 0 1 0 0
leetcode85.最大矩形_第2张图片
矩阵前2行形成的柱状图:2 0 2 1 1
leetcode85.最大矩形_第3张图片
矩阵前3行形成的柱状图:3 1 3 2 2
leetcode85.最大矩形_第4张图片
矩阵前4行形成的柱状图:4 0 0 3 0
leetcode85.最大矩形_第5张图片
对每个柱状图调用maxArea求最大矩形面积,取所有面积的最大值即为所求。

Java

class Solution {
    public int maximalRectangle(char[][] matrix) {
        if (matrix.length == 0) {
            return 0;
        }

        int[] nums = new int[matrix[0].length];
        int result = 0;

        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                nums[j] = matrix[i][j] == '1' ? nums[j] + 1 : 0;
            }
            result = Math.max(result, maxArea(nums));
        }

        return result;
    }

    // 参见 https://leetcode.cn/problems/largest-rectangle-in-histogram/
    private int maxArea(int[] nums) {
        // left[i]表示nums[i]左边第一个小于nums[i]的元素下标
        int[] left = new int[nums.length];
        left[0] = -1;
        for (int i = 1; i < nums.length; i++) {
            int j = i - 1;
            while (j != -1 && nums[j] >= nums[i]) {
                j = left[j];
            }
            left[i] = j;
        }

        // right[i]表示nums[i]右边第一个小于nums[i]的元素下标
        int[] right = new int[nums.length];
        right[nums.length - 1] = nums.length;
        for (int i = nums.length - 2; i >= 0; i--) {
            int j = i + 1;
            while (j != nums.length && nums[j] >= nums[i]) {
                j = right[j];
            }
            right[i] = j;
        }

        int result = 0;
        for (int i = 0; i < nums.length; i++) {
            result = Math.max(result, nums[i] * (right[i] - left[i] - 1));
        }

        return result;
    }
}

Go

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

	max := func(a, b int) int {
		if a > b {
			return a
		}
		return b
	}

	// 参见 https://leetcode.cn/problems/largest-rectangle-in-histogram/
	maxAreaOfRow := func(nums []int) int {
		// left[i]表示nums[i]左边第一个比nums[i]小的元素下标
		left := make([]int, len(nums))
		left[0] = -1
		for i := 1; i < len(nums); i++ {
			idx := i - 1
			for idx != -1 && nums[idx] >= nums[i] {
				idx = left[idx]
			}
			left[i] = idx
		}

		// right[i]表示nums[i]右边第一个比nums[i]小的元素下标
		right := make([]int, len(nums))
		right[len(nums)-1] = len(nums)
		for i := len(nums) - 2; i >= 0; i-- {
			idx := i + 1
			for idx != len(nums) && nums[idx] >= nums[i] {
				idx = right[idx]
			}
			right[i] = idx
		}

		maxArea := 0
		for i := 0; i < len(nums); i++ {
			maxArea = max(maxArea, nums[i]*(right[i]-left[i]-1))
		}

		return maxArea
	}

	row := make([]int, len(nums[0]))
	maxArea := 0
	for i := 0; i < len(nums); i++ {
		for j := 0; j < len(nums[i]); j++ {
			if nums[i][j] == '0' {
				row[j] = 0
			} else {
				row[j]++
			}
		}
		maxArea = max(maxArea, maxAreaOfRow(row))
	}

	return maxArea
}

你可能感兴趣的:(leetcode,算法,算法,leetcode)