LeetCode_Maximal Rectangle

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

题目描述十分简单,就是求给定0,1数组中全1子矩阵的最大1数目。

LeetCode_Largest Rectangle in Histogram我们已经可以对直方图的最大矩形面积进行求解,这道题目只需要转换成直方图的矩形面积问题就非常简单了。

我们使用dp[]数组来记录到第i行为止,第j个位置垂直连续包含多少个1(包括matrxi[i][j])。如:

1 0 1 1 0

1 1 0 1 0

0 1 1 1 1

有如下结果:

第1行: dp[] = {1, 0, 1, 1, 0}

第2行: dp[] = {2, 1, 0, 2, 0}

第3行: dp[] = {0, 2, 1, 3, 0}

显然这里的dp数组就是我Largest Rectangle in Histogram中的height数组,因此直接使用直方图最大矩形面积的求解方法就可以。

这样的算法时间复杂度是O(n^2),空间复杂度O(n)

class Solution {
public:
    int maximalRectangle(vector<vector<char> > &matrix) {
        if(matrix.size() == 0) return 0;
        if(matrix[0].size() == 0) return 0;

        vector <int> dp(matrix[0].size(),0);
        for(int i=0; i<matrix[0].size(); i++){
        	if(matrix[0][i]=='1'){
        		dp[i] = 1;
        	}
        }
        int res = largestRectangleArea(dp);

        for(int i=1; i<matrix.size(); i++){
        	for(int j=0; j<matrix[0].size();j++){
        		if(matrix[i][j] == '1'){
        			dp[j] = dp[j]+1;
        		}
        		else{
        			dp[j] = 0;
        		}
        	}
        	int cur = largestRectangleArea(dp);
        	if(cur > res){
        		res = cur;
        	}
        }

        return res;
    }
private:
    int largestRectangleArea(vector<int> &height) {
        if(height.size()==0){
            return 0;
        }

        //Create an empty stack. The stack holds indexes of 
        //vector <int> height.
        //The bars stored in stack are always in increasing order
        //of their heights 
        stack <int> s;

        int max_area = 0; //Initialize max area
        int tp; //To store top of stack 
        int area_with_top; //to store area with top bar as the smallest bar

        //Run through all bars of given histogram
        int i = 0;

        while(i < height.size()){
            //If this bar is higher than the bar on the stack, push it to stack
            if(s.empty() || height[s.top()] <= height[i]){
                s.push(i++);
            }

            //If this bar is lower than top of stack, then calculate area
            //with stack top as the smallest (or mimimum height) bar. 'i' is 
            //'right index' for the top and element before top in stack is 
            //'left index'
            else {
                tp = s.top(); //store the top index
                s.pop(); //pop the top

                //Calculate the area with height[tp] stack as smallest bar
                area_with_top = height[tp]*(s.empty()?i:i-s.top()-1);

                //update max area, if needed
                if(max_area < area_with_top){
                    max_area = area_with_top;
                } 
            }
        }

        //Now pop the remaining bars from stack and calculate area with
        //elements popped bar as the smallest bar
        while(s.empty() == false){
            tp = s.top();
            s.pop();
            area_with_top = height[tp]*(s.empty()?i:i-s.top()-1);
            if(max_area<area_with_top){
                max_area = area_with_top;
            }
        }

        return max_area;
    } 
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目描述: 给定一个字符串,请将字符串里的字符按照出现的频率降序排列。 示例 1: 输入: "tree" 输出: "eert" 解释: 'e'出现两次,'r'和't'都只出现一次。因此'e'必须出现在'r'和't'之前。此外,"eetr"也是一个有效的答案。 示例 2: 输入: "cccaaa" 输出: "cccaaa" 解释: 'c'和'a'都出现三次。此外,"aaaccc"也是有效的答案。注意"cacaca"是不正确的,因为相同的字母必须放在一起。 示例 3: 输入: "Aabb" 输出: "bbAa" 解释: 此外,"bbaA"也是一个有效的答案,但"Aabb"是不正确的。注意'A'和'a'被认为是两种不同的字符。 Java代码如下: ``` import java.util.*; public class Solution { public String frequencySort(String s) { if (s == null || s.length() == 0) { return ""; } Map<Character, Integer> map = new HashMap<>(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); map.put(c, map.getOrDefault(c, 0) + 1); } List<Map.Entry<Character, Integer>> list = new ArrayList<>(map.entrySet()); Collections.sort(list, (o1, o2) -> o2.getValue() - o1.getValue()); StringBuilder sb = new StringBuilder(); for (Map.Entry<Character, Integer> entry : list) { char c = entry.getKey(); int count = entry.getValue(); for (int i = 0; i < count; i++) { sb.append(c); } } return sb.toString(); } } ``` 解题思路: 首先遍历字符串,使用HashMap记录每个字符出现的次数。然后将HashMap转换为List,并按照出现次数从大到小进行排序。最后遍历排序后的List,将每个字符按照出现次数依次添加到StringBuilder中,并返回StringBuilder的字符串形式。 时间复杂度:O(nlogn),其中n为字符串s的长度。遍历字符串的时间复杂度为O(n),HashMap和List的操作时间复杂度均为O(n),排序时间复杂度为O(nlogn),StringBuilder操作时间复杂度为O(n)。因此总时间复杂度为O(nlogn)。 空间复杂度:O(n),其中n为字符串s的长度。HashMap和List的空间复杂度均为O(n),StringBuilder的空间复杂度也为O(n)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值