LeetCode Summary
  • Introduction
  • DP, 动态规划类
    • Best Time to Buy and Sell Stock III 题解
    • Best Time to Buy and Sell Stock 题解
    • Climbing Stairs 题解
    • Decode Ways 题解
    • Distinct Subsequences 题解
    • Edit Distance 题解
    • Interleaving String 题解
    • Longest Palindromic Substring 题解
    • Maximum Product Subarray 题解
    • Maximum Subarray 题解
    • Minimum Path Sum 题解
    • Palindrome Partitioning 题解
    • Palindrome Partitioning II 题解
    • Scramble String 题解
    • Triangle 题解
    • Unique Binary Search Trees 题解
    • Unique Paths II 题解
    • Word Break 题解
    • Word Break II 题解
  • list, 链表相关
    • Add Two Numbers 题解
    • Convert Sorted List to Binary Search Tree 题解
    • Copy List with Random Pointer 题解
    • Insertion Sort List 题解
    • LRU Cache 题解
    • Linked List Cycle 题解
    • Linked List Cycle II 题解
    • Merge Two Sorted Lists 题解
    • Merge k Sorted Lists 题解
    • Partition List 题解
    • Remove Duplicates from Sorted List 题解
    • Remove Duplicates from Sorted List II 题解
    • Remove Nth Node From End of List 题解
    • Reorder List 题解
    • Reverse Linked List II 题解
    • Reverse Nodes in k-Group 题解
    • Rotate List 题解
    • Sort List 题解
    • Swap Nodes in Pairs 题解
  • binary tree, 二叉树相关
    • Balanced Binary Tree 题解
    • Binary Tree Inorder Traversal 题解
    • Binary Tree Level Order Traversal 题解
    • Binary Tree Level Order Traversal II 题解
    • Binary Tree Maximum Path Sum 题解
    • Binary Tree Postorder Traversal 题解
    • Binary Tree Preorder Traversal 题解
    • Binary Tree Zigzag Level Order Traversal 题解
    • Construct Binary Tree from Inorder and Postorder Traversal 题解
    • Construct Binary Tree from Preorder and Inorder Traversal 题解
    • Convert Sorted List to Binary Search Tree 题解
    • Flatten Binary Tree to Linked List 题解
    • Maximum Depth of Binary Tree 题解
    • Minimum Depth of Binary Tree 题解
    • Path Sum 题解
    • Path Sum II 题解
    • Populating Next Right Pointers in Each Node 题解
    • Populating Next Right Pointers in Each Node II 题解
    • Recover Binary Search Tree 题解
    • Same Tree 题解
    • Sum Root to Leaf Numbers 题解
    • Symmetric Tree 题解
    • Unique Binary Search Trees 题解
    • Unique Binary Search Trees II 题解
    • Validate Binary Search Tree 题解
  • sort, 排序相关
    • 3Sum Closest 题解
    • 3Sum 题解
    • 4Sum 题解
    • Insert Interval 题解
    • Longest Consecutive Sequence 题解
    • Merge Intervals 题解
    • Merge Sorted Array 题解
    • Remove Duplicates from Sorted Array 题解
    • Remove Duplicates from Sorted Array II 题解
    • Sort Colors 题解
    • Two Sum 题解
  • search, 搜索相关
    • First Missing Positive 题解
    • Find Minimum in Rotated Sorted Array 题解
    • Find Minimum in Rotated Sorted Array II 题解
    • Median of Two Sorted Arrays 题解
    • Search Insert Position 题解
    • Search a 2D Matrix 题解
    • Search for a Range 题解
    • Search in Rotated Sorted Array 题解
    • Search in Rotated Sorted Array II 题解
    • Single Number 题解
    • Single Number II 题解
  • math, 数学类相关
    • Add Binary 题解
    • Add Two Numbers 题解
    • Divide Two Integers 题解
    • Gray Code 题解
    • Integer to Roman 题解
    • Multiply Strings 题解
    • Palindrome Number 题解
    • Plus One 题解
    • [Pow(x, n) 题解](math/Pow(x,-n).md)
    • Reverse Integer 题解
    • Roman to Integer 题解
    • [Sqrt(x) 题解](math/Sqrt(x).md)
    • [String to Integer (atoi) 题解](math/String-to-Integer-(atoi).md)
    • Valid Number 题解
  • string, 字符串处理相关
    • Anagrams 题解
    • Count and Say 题解
    • Evaluate Reverse Polish Notation 题解
    • [Implement strStr() 题解](string/Implement-strStr().md)
    • Length of Last Word 题解
    • Longest Common Prefix 题解
    • Longest Palindromic Substring 题解
    • Longest Substring Without Repeating Characters 题解
    • Longest Valid Parentheses 题解
    • Minimum Window Substring 题解
    • Regular Expression Matching 题解
    • Reverse Words in a String 题解
    • Simplify Path 题解
    • Text Justification 题解
    • Valid Parentheses 题解
    • Wildcard Matching 题解
    • ZigZag Conversion 题解
  • combination and permutation, 排列组合相关
    • Combinations 题解
    • Combination Sum 题解
    • Combination Sum II 题解
    • Letter Combinations of a Phone Number 题解
    • Next Permutation 题解
    • Palindrome Partitioning 题解
    • Permutation Sequence 题解
    • Permutations 题解
    • Permutations II 题解
    • Subsets 题解
    • Subsets II 题解
    • Unique Paths 题解
  • matrix, 二维数组, 矩阵相关
    • Rotate Image 题解
    • Set Matrix Zeroes 题解
    • Spiral Matrix 题解
    • Spiral Matrix II 题解
    • Maximal Rectangle 题解
  • 回溯, BFS/DFS
    • Clone Graph 题解
    • Generate Parentheses 题解
    • N-Queens 题解
    • N-Queens II 题解
    • Restore IP Addresses 题解
    • Sudoku Solver 题解
    • Surrounded Regions 题解
    • Word Ladder 题解
    • Word Ladder II 题解
    • Word Search 题解
  • greedy, 贪心
    • Best Time to Buy and Sell Stock II 题解
    • Jump Game 题解
    • Jump Game II 题解
  • 其他
    • Candy 题解
    • Container With Most Water 题解
    • Gas Station 题解
    • Gray Code 题解
    • Max Points on a Line 题解
    • [Pascal's Triangle 题解](others/Pascal's-Triangle.md)
    • [Pascal's Triangle II 题解](others/Pascal's-Triangle-II.md)
    • Remove Element 题解
    • Trapping Rain Water 题解
Powered by GitBook
On this page
  • O(n^3) 算法
  • O(n^2)算法
  • O(n^2)算法 思路2

Was this helpful?

  1. matrix, 二维数组, 矩阵相关

Maximal Rectangle 题解

PreviousSpiral Matrix II 题解Next回溯, BFS/DFS

Last updated 5 years ago

Was this helpful?

题目来源:

> Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.

解题思路:

O(n^3) 算法

一种直接的方法是: 横向记录从左到i, 包括i为1的连续1的长度,然后再纵向去查找以这个连续1长度作为min宽的最大的高度,得到面积。O(n^3)

    int getMaxHeight(const vector<vector<int> > &ones, int row, int col)
    {
        int minWidth = ones[row][col];
        int height = 0;
        for(int i = row; i >= 0; i--) //up
        {
            if(ones[i][col] >= minWidth)
                ++height;
            else 
                break;
        }
        for(int i = row+1; i < ones.size(); i++)
        {
            if(ones[i][col] >= minWidth)
                ++height;
            else
                break;
        }
        return height;
    }
    int maximalRectangle(vector<vector<char> > &matrix) 
    {
        int m = matrix.size(); if(m == 0) return 0;
        int n = matrix[0].size();
        vector<vector<int> > ones(m, vector<int>(n, 0));//[i][j], 第i行从左到j, 包括j连续1的长度
        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++)
            {
                if(j == 0) ones[i][0] = matrix[i][j] == '1' ? 1 : 0;
                else ones[i][j] = matrix[i][j] == '1' ? ones[i][j-1]+1 : 0;
            }
        int result = 0;
        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++)
            {
                if(ones[i][j] > 0)
                    result = std::max(result, ones[i][j] * getMaxHeight(ones, i, j));
            }
        return result;
    }

O(n^2)算法

用栈维护了一个递增(非递减)的序列,当当前索引的元素比栈顶小时,取栈顶元素(并出栈),并将这个元素的高度和当前索引端(快降低了)构成的矩形面积,栈中上升的那段都可以出栈并计算。

    int largestRectangleArea(const vector<int> &height)
    {
        int result = 0;
        stack<int> index;
        for(int i = 0; i < height.size(); i++)
        {
            if(index.empty() || height[index.top()] <= height[i] )
                index.push(i);
            else
            {
                while(!index.empty() && height[index.top()] >= height[i])
                {
                    auto t = index.top();
                    index.pop();
                    result = std::max(result, height[t] * (index.empty() ? i : (i-1)-index.top()));
                }
                index.push(i);//Do not forget.
            }
        }
        return result;
    }

    int maximalRectangle(vector<vector<char> > &matrix) 
    {
        int m = matrix.size(); if(m == 0) return 0;
        int n = matrix[0].size();
        vector<vector<int> > ones(m, vector<int>(n, 0));
        int result = 0;
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(i == 0) ones[0][j] = matrix[i][j] == '1' ? 1 : 0;
                else ones[i][j] = matrix[i][j] == '1' ? ones[i-1][j]+1 : 0;
            }
            ones[i].push_back(-1);
            result = std::max(result, largestRectangleArea(ones[i]));
        }
        return result;
    }
[0,2,3,]-->[0,2,]
4*(4-1-2)=8.
[0,2] --> [0]
3*(4-1-0)=9. !!max
[0] -->[]
2*(4)=8.

上面代码还可以优化下内存空间, 用O(n)n为列数量。

    int maximalRectangle2(vector <string > & matrix)
    {
        int m = matrix.size(); if (m == 0) return 0;
        int n = matrix[0].size(); if (n == 0) return 0;
        vector< int> height(n+1, 0);
        int maxArea = 0;
        for(int row = 0; row < m; row++)
        {
            for(int col = 0; col < n; col++)
            {
                if(matrix [row][col] == '1')
                    height[col] += 1;
                else
                    height[col] = 0;
            }
            height[n] = -1; //dummy one
            maxArea = std::max(maxArea, largestRectangleArea(height));
        }
        return maxArea;
    }

O(n^2)算法 思路2

    int maximalRectangle(vector<vector<char> > &matrix) 
    {
        int m = matrix.size(); if(m == 0) return 0;
        int n = matrix[0].size();
        int result = 0;
        vector<int> leftMax(n, -1);
        vector<int> rightMin(n, n);
        vector<int> height(n, 0);
        for(int i = 0; i < m; i++)
        {
            int left = -1, right = n;
            for(int j = 0; j < n; j++)
            {
                if(matrix[i][j] == '1'){
                    ++height[j];
                    leftMax[j] = std::max(leftMax[j], left);
                }else{
                    left = j;
                    height[j]=0; leftMax[j]=-1; rightMin[j]=n;
                }
            }
            for(int j = n-1; j >= 0; j--)
            {
                 if(matrix[i][j] == '1'){
                     rightMin[j] = std::min(rightMin[j], right);
                     result = std::max(result, height[j]*(rightMin[j]-leftMax[j]-1));
                 }else{
                     right = j;
                 }
            }
        }
        return result;
    }

一行一行处理,每一行,按照柱状图那道题目 O(n)算法处理,总体复杂度O(n^2).

以高度[2,5,3,4,1]为例, 2[index=0], 5[index=2]进栈, 当前高度为3, 以5为最矮的计算面积为5,然后5出栈, 此时把3[index=2]进栈 (注意对比下的写法), 一直到index=4时,1最小了, 依次计算面积,

参考了。 思路是对当前高度h, 找左边比他小的最大的index,设为i, 右边比h小最小的index,设为j,则以h为最小高度的面积应该为 (j-i-1)*h. eg : [2,5,3,4,1], 当前高度3, 则, left=0, right = 4, area = 3*(4-0-1)=9.

Maximal Rectangle
Largest Rectangle in Histogram
Largest Rectangle in Histogram
leetcode-cpp