剑指offer 专项突破版 40、矩阵中最大的矩形

题目链接

思路

这种题目感觉很像初中的平面几何,看上去无从下手但是添加一个辅助线就很简单了。。。。。。但不看答案肯定想不出来辅助线是怎么加的/(ㄒoㄒ)/~~

  • 可以把该问题转化为上一道题,具体做法为遍历矩阵的每一行,每一行可以得到一个heights数组,然后利用上一题的函数计算最大值
  • 具体数组的计算方式为:计算和该行上方相邻的1的数目
for (int i = 0; i < s.length(); i++) {
    if ('0' == s.charAt(i))
        height[i] = 0;
    else
        height[i]++;
}

AC代码

class Solution {
    public int largestRectangleArea(int[] heights) {

        int max = Integer.MIN_VALUE;
        Stack<Integer> s = new Stack<>();
        s.push(-1);

        for (int i = 0; i < heights.length; i++) {

            while (-1 != s.peek() && heights[i] < heights[s.peek()]) {
                int index = s.pop();
                max = Math.max(max, (i - s.peek() - 1) * heights[index]);
            }
            s.push(i);
        }

        while (-1 != s.peek()) {
            int index = s.pop();
            max = Math.max(max, (heights.length - s.peek() - 1) * heights[index]);
        }

        return max;
    }

    public int maximalRectangle(String[] matrix) {
        if (0 == matrix.length || 0 == matrix[0].length())
            return 0;

        int[] height = new int[matrix[0].length()];
        int maxSize = 0;

        for (String s : matrix) {
            for (int i = 0; i < s.length(); i++) {
                if ('0' == s.charAt(i))
                    height[i] = 0;
                else
                    height[i]++;
            }
            maxSize = Math.max(maxSize, largestRectangleArea(height));
        }
        return maxSize;
    }
}
Go代码
func maximalRectangle(matrix []string) int {
	if len(matrix) == 0 {
		return 0
	}
	result := 0
	height := make([]int, len(matrix[0]))

	for _, str := range matrix {
		for i, ch := range str {
			if ch == '0' {
				height[i] = 0
			} else {
				height[i]++
			}
		}
        result = max(result, largestRectangleArea(height))
	}
	return result
}

func largestRectangleArea(heights []int) (result int) {
	var stack []int

	for i, height := range heights {
		for len(stack) != 0 && heights[stack[len(stack)-1]] >= height {
			rectangleHeight := heights[stack[len(stack)-1]]
			stack = stack[0 : len(stack)-1]
			var left int
			if len(stack) == 0 {
				left = -1
			} else {
				left = stack[len(stack)-1]
			}
			result = max(result, rectangleHeight*(i-left-1))
		}
		stack = append(stack, i)
	}

	right := len(heights)
	for len(stack) != 0 {
		height := heights[stack[len(stack)-1]]
		stack = stack[0 : len(stack)-1]
		var left int
		if len(stack) == 0 {
			left = -1
		} else {
			left = stack[len(stack)-1]
		}
		result = max(result, height*(right-left-1))
	}

	return
}

func max(m, n int) int {
	if m >= n {
		return m
	}
	return n
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值