leetcode day04 贪心、DP、栈算法练习

11.盛最多水的容器

//贪心算法->双指针:以双指针为左右边界(即数组的左右边界)计算出的容量中的最大值
class Solution {
public:
    int maxArea(vector<int>& height) {
        int l=0,r=height.size()-1;
        int ans=0;
        while(l<r){
            int area = min(height[l],height[r])*(r-l);
            ans = max(ans,area);
            if(height[l]<=height[r]){
                ++l;
            }
            else{
                --r;
            }
        }
        return ans;
    }
};

作者:力扣官方题解
链接:https://leetcode.cn/problems/container-with-most-water/solutions/207215/sheng-zui-duo-shui-de-rong-qi-by-leetcode-solution/
 

 

44.通配符的匹配 

方法:动态规划 

class Solution {
public:
    bool isMatch(string s, string p) {
        int m=p.size(),n=s.size();
        vector<vector<int>> dp(m+1,vector<int>(n+1));
        dp[0][0]=true;
        for(int i=1;i<=m;i++)
        {
            for(int j=0;j<=n;j++)
            {
                if(p[i-1]=='*' && dp[i-1][j])  //'*' 优先级最高,先判断它
                {
                    while(j<=n) dp[i][j++]=true;
                    break;
                }
                //后续确定是否为T时,需要用到左上角数据当j=0,需要设为F
                //(唯一为T的情况,已经在*时判断了)
                if(!j) 
                { 
                    dp[i][j]=false;
                    continue;
                }
                //然后再判断?
                if(p[i-1]=='?'&&dp[i-1][j-1])
                { 
                    dp[i][j]=true;
                    continue;
                }
                //最后为正常情况
                if(dp[i-1][j-1]&&p[i-1]==s[j-1]) dp[i][j]=true;
                else dp[i][j]=false;
            }
        }
        return (bool)dp[m][n];//返回最右下角位置的bool值
    }
};

(这个作者讲的动态规划题解真的超级超级详细!配有图文的,一看就会了,佬哇!)

(作者:狗大王

链接:https://leetcode.cn/problems/wildcard-matching/solutions/1/yi-ge-qi-pan-kan-dong-dong-tai-gui-hua-dpsi-lu-by-/)

53.最大子数组和

我记得之前是在学算法的时候,在书上看到这题用了分治法。不过这次看到题解发现用动态规划原来这么简单!!我丢

方法一:动态规划

//动态规划
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int pre = 0,maxAns = nums[0];
        for(const auto &x:nums){
            pre = max(pre + x, x);
            maxAns = max(maxAns,pre);
        }
        return maxAns;
    }
};

 方法二:分治算法

//以后再补上,我想先把动态规划的多刷刷。

 

63.不同路径 II

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        int m = obstacleGrid.size(),n = obstacleGrid.at(0).size();
        vector<int> f(n);
        f[0] = (obstacleGrid[0][0] == 0);
        if(f[0]==0) return 0;
        for(int i=0;i<m;++i){
            for(int j=0;j<n;++j){
                if(obstacleGrid[i][j]==1){
                    f[j] = 0;
                    continue;
                }
                if(j-1>=0 && obstacleGrid[i][j-1]==0){
                    f[j] +=f[j-1];
                }
            }
        }
        return f.back();
    }
};
//dp数组二维压缩到一维,原理就是从上到下的路径是继承的,而从左到右的路径是累加的。

84.柱状图中最大的矩形

方法一:暴力求解+一点优化

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size();
        if(n==0) return 0;
        if(n==1) return heights[0];
        int maxs = 0,mins = 0;
        for(int i=0;i<n;i++){
            mins = heights[i];
            int j = i;
            maxs = max(heights[i],maxs);
            while(++j<n){
                mins = min(mins,heights[j]);
                if(mins * (n-i) < maxs) break; 
                //如果当时的最小值✖总长度都比当前的最大面积小的话,那从这一个i开始的面积就可以放弃了。
                maxs = max(maxs,mins * (j-i+1));
            }
        }
        return  maxs;      
    }
};

方法二:单调栈

(题解来自博客:[C++] LeetCode 84. 柱状图中最大的矩形_c++给出一张柱状图,每根柱子的宽度为1,高度为hi,现在请你求出柱状图中最大矩形的-CSDN博客讲解真的很清晰!!爱了)

//方法二:单调栈
class Solution{
public:
    int largestRectangleArea(vector<int>& heights){
        int n = heights.size();
        stack<int> index;
        int area = 0;
        for(int i=0;i<heights.size();i++){
            if(index.empty() || heights[index.top()]<heights[i]) index.push(i);
            else{
                while(!index.empty() && heights[index.top()]>=heights[i]){
                    int tmp = index.top();
                    index.pop();
                    int length = 0;
                    if(index.empty()) length = i;
                    else length = i-index.top()-1;
                    area = max(area,length * heights[tmp]);
                }
                index.push(i);
            }
        }
        while(!index.empty()){
            int tmp = index.top();
            index.pop();
            int length = 0;
            if(index.empty()) length = n;
            else length = n-index.top()-1;
            area = max(area,length * heights[tmp]);
        }
        return area;
    }
};

 

85.最大矩形 

牛逼的思路

class Solution {
public:
    int largestRectangleArea(vector<int>& heights){
        int n = heights.size();
        stack<int> index;
        int area = 0;
        for(int i=0;i<heights.size();i++){
            if(index.empty() || heights[index.top()]<heights[i]) index.push(i);
            else{
                while(!index.empty() && heights[index.top()]>=heights[i]){
                    int tmp = index.top();
                    index.pop();
                    int length = 0;
                    if(index.empty()) length = i;
                    else length = i-index.top()-1;
                    area = max(area,length * heights[tmp]);
                }
                index.push(i);
            }
        }
        while(!index.empty()){
            int tmp = index.top();
            index.pop();
            int length = 0;
            if(index.empty()) length = n;
            else length = n-index.top()-1;
            area = max(area,length * heights[tmp]);
        }
        return area;
    }
    int maximalRectangle(vector<vector<char>>& matrix) {
        if(matrix.size()==0 || matrix[0].size()==0){
            return 0;
        }
        int m = matrix.size();
        int n = matrix[0].size();
        vector<int> heights(n);
        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;
    }
};

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值