列表

详情


NC237. 最大矩形

描述

给定一个仅包含 0 和 1 ,大小为 n*m 的二维二进制矩阵,找出仅包含 1 的最大矩形并返回面积。

数据范围: 保证输入的矩形中仅含有 0 和 1

例如输入[[1,0,1,0,0],[1,1,1,1,0],[1,1,1,1,1],[1,0,0,1,0]]时,对应的输出为8,所形成的最大矩形如下图所示:

示例1

输入:

[[1]]

输出:

1

示例2

输入:

[[1,1],[0,1]]

输出:

2

说明:

第一列的两个 1 组成一个矩形

示例3

输入:

[[0,0],[0,0]]

输出:

0

示例4

输入:

[[1,0,1,0,0],[1,1,1,1,0],[1,1,1,1,1],[1,0,0,1,0]]

输出:

8

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 5ms, 内存消耗: 676KB, 提交时间: 2022-02-10

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param matrix int整型vector<vector<>> 
     * @return int整型
     */
    int maximalRectangle(vector<vector<int> >& matrix) {
        // write code here
        int maxArea = 0;
        
        int m = matrix.size();
        int n = matrix[0].size();
        
        for(int i = 0; i < m; ++i){
            for(int j = 0; j < n; ++j){
                if(matrix[i][j]){
                    if(j)
                        matrix[i][j] = matrix[i][j - 1] + 1;
                    int len = matrix[i][j];
                    int height = 1;
                    while(i - height + 1 >= 0 && matrix[i - height + 1][j]){
                        len = min(len, matrix[i - height + 1][j]);
                        maxArea = max(maxArea, len * height);
                        ++height;
                    }
                }
            }
        }
        
        return maxArea;
    }
};

C 解法, 执行用时: 6ms, 内存消耗: 640KB, 提交时间: 2022-06-05

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param matrix int整型二维数组 
 * @param matrixRowLen int matrix数组行数
 * @param matrixColLen int* matrix数组列数
 * @return int整型
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
int max(int a, int b) {
    return a > b ? a : b;
}

int largestRectangleArea(int *heights, int cols) {
    // 判断height,为空直接返回0
    if (cols == 0) {
        return 0;
    }
    
    int res = 0;
    int *h = (int *)malloc(sizeof(int) * (cols + 2));
    memcpy(h + 1, heights, sizeof(int) * cols);
    h[0] = 0;
    h[cols+1] = 0;
    int n = cols + 2;
    
    int stack[203] = {0};
    int sTop = 0;
    int curWidth = 0;
    int curHeight = 0;
    
    for (int i = 0; i < n; i++) {
        while ((sTop > 0) && (h[i] < h[stack[sTop-1]])) {
            if (sTop - 2 >= 0) {
                curWidth = i - stack[sTop - 2] - 1;
            } else {
                curWidth = i;
            }
            
            curHeight = h[stack[sTop-1]];
            sTop--;

            res = max(res, curWidth * curHeight);
        }
        
        stack[sTop++] = i;
    }
        
    free(h);
    return res;
}

int maximalRectangle(int** matrix, int matrixRowLen, int* matrixColLen ) {
    // 获取矩阵的长宽
    if (matrix == NULL || matrixRowLen == 0) {
        return 0;
    }
    
    int rows = matrixRowLen;
    int cols = *matrixColLen;
    int *heights = (int *)malloc(sizeof(int) * cols);
    memset(heights, 0, sizeof(int) * cols);
    int res = 0;
    // 预处理矩阵
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            if (matrix[i][j] == 1) {
                heights[j] = heights[j] + 1;
            } else {
                heights[j] = 0;
            }
        }
        
        res = max(res, largestRectangleArea(heights, cols));
    }
    
    free(heights);
    
    return res;
}


C++ 解法, 执行用时: 6ms, 内存消耗: 680KB, 提交时间: 2022-05-03

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param matrix int整型vector<vector<>> 
     * @return int整型
     */
        int largestRectangleArea(vector<int>& heights){
        stack<int> s;
        s.push(-1);
        int ans=0;
        for(int i=0;i<heights.size();++i){
            while(s.top()!=-1 && heights[i]<=heights[s.top()]){
                    int index=s.top();
                    s.pop();
                    ans=max(ans,heights[index]*(i-s.top()-1));   
            }
            s.push(i);
        }
        while(s.top()!=-1){
            int index=s.top();
            s.pop();
            ans=max(ans,heights[index]*((int)(heights.size())-s.top()-1));
        }
        return ans;
    }
    int maximalRectangle(vector<vector<int> >& matrix) {
        // write code here
        int m=matrix.size(),n=matrix[0].size();
        vector<int> heights(n,0);
        int ans=0;
        for(int i=0;i<m;++i){
            for(int j=0;j<n;++j){
                if(matrix[i][j]==1) heights[j]+=1;
                else{
                    heights[j]=0;
                }
            }
            ans=max(ans,largestRectangleArea(heights));
        }
        return ans;
    }
};

C++ 解法, 执行用时: 6ms, 内存消耗: 692KB, 提交时间: 2022-04-01

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param matrix int整型vector<vector<>> 
     * @return int整型
     */
    int largestRectangle(vector<int>& height) {
		int n = height.size();
		vector<int> left(n);
		vector<int> right(n);
		stack<int> monoStack;
		int res = 0;
		for (int i = 0; i < n; ++i) {
			while (!monoStack.empty() && height[i] <= height[monoStack.top()])
				monoStack.pop();
			left[i] = monoStack.empty() ? -1 : monoStack.top(); //注意!返回的是单调栈的栈顶
			monoStack.push(i);
		}
		monoStack = stack<int>(); 
		for (int i = n - 1; i >= 0; --i) {	//注意 i从n-1开始
			while (!monoStack.empty() && height[i] <= height[monoStack.top()])
				monoStack.pop();
			right[i] = monoStack.empty() ? n : monoStack.top(); //注意!返回的是单调栈的栈顶
			monoStack.push(i);
		}
		for (int i = 0; i < n; ++i)
			res = max(res, (right[i] - left[i] - 1) * height[i]);
		return res;
	}
    int maximalRectangle(vector<vector<int> >& matrix) {
        int m = matrix.size();
		int n = matrix[0].size();
		vector<int> height(n);
		int res = 0;
		for (int i = 0; i < m; ++i) {
			for (int j = 0; j < n; ++j) {
				if (matrix[i][j] == 1) //注意 是数字1
					height[j]++;
				else
					height[j] = 0;
			}
			res = max(res, largestRectangle(height));
		}
		return res;
    }
};

C++ 解法, 执行用时: 6ms, 内存消耗: 716KB, 提交时间: 2022-01-26

class Solution {
public:
    /*
    单调栈
    */
    int maximalRectangle(vector<vector<int>> &mat) {
        int j, mx_h, mx_area;
        int n = mat.size();
        int m = mat[0].size();
        vector<int> h_arr(n, 0);
        
        // 按列构造直方图
        for(int i = 0; i < n; i++) {
            for(int j = m-2; j >=0; j--) {
                mat[i][j] = (mat[i][j] == 1) ? (mat[i][j] + mat[i][j+1]) : 0;
            }
        }
        
        // 按列开始找最大直方图的矩形面积
        j = 0;
        mx_area = 0;
        while(j < m) {
            mx_h = 0;
            for(int i = 0; i < n; i++) {
                h_arr[i] = mat[i][j];
                mx_h = max(mx_h, h_arr[i]);
            }
            if(mx_h == 0) { // 重要剪枝
                j++;
                continue;
            }
            mx_area = max(mx_area, fn_large_area(h_arr));
            j++;
        }
        
        return mx_area;
    }
     
private:
    // 单调栈
    int fn_large_area(vector<int> &nums) {
        stack<int> stk; // 存放索引
        int n = nums.size();
        int h, l_idx, mx_area;
        
        mx_area = 0;
        for(int i = 0; i < n; i++) {
            while(!stk.empty() && nums[i] < nums[stk.top()]) { // 违背单调栈条件时
                h = nums[stk.top()]; stk.pop();
                l_idx = stk.empty() ? 0 : (stk.top() + 1);
                mx_area = max(mx_area, h * (i - l_idx)); // 统计递减矩形最大面积
            }
            stk.push(i);
        }
        
        while(!stk.empty()) { // 单调栈统计矩形最大面积
            h = nums[stk.top()]; stk.pop();
            l_idx = stk.empty() ? 0 : (stk.top() + 1);
            mx_area = max(mx_area, h * (n - l_idx));
        }
        
        return mx_area;
    }
};

上一题