2021-04-02~04力扣三天集合

这篇博客探讨了三个算法问题:1) 使用单调栈解决直方图的水量计算;2) 应用动态规划求解两个字符串的最长公共子序列;3) 分析如何根据兔子的回答确定森林中兔子的最小数量。通过实例和解题思路,深入理解这些算法的应用。
摘要由CSDN通过智能技术生成

20210402题号:面试题 17.21. 直方图的水量

题目描述

给定一个直方图(也称柱状图),假设有人从上面源源不断地倒水,最后直方图能存多少水量?直方图的宽度为 1。
在这里插入图片描述
上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的直方图,在这种情况下,可以接 6 个单位的水(蓝色部分表示水)。 感谢 Marcos 贡献此图。

解题思路:单调栈
解答
class Solution {
public:
    int trap(vector<int>& height) {
        int n=height.size();
        if(n==0)return 0;
        //单调栈
        stack<int> grap;
        grap.push(0);
        int sum=0;
        for(int i=1;i<n;i++){
            if(grap.empty()){
                grap.push(i);
            }
            else if(height[i]<=height[grap.top()]){
                grap.push(i);
            }else{ 
                int pre=grap.top();
                grap.pop();
                int back;
                while(!grap.empty()&&height[grap.top()]<=height[i]){
                    back=grap.top();
                    sum+=(height[back]-height[pre])*(i-back-1);
                    grap.pop();
                    pre=back;
                }
                //目前的栈顶元素大于height[i]
                if(!grap.empty()){
                    sum+=(height[i]-height[pre])*(i-grap.top()-1);
                    grap.push(i);
                }else grap.push(i);
            }
            
        }
        return sum;
    }
};

20210403题号:1143. 最长公共子序列

题目描述

给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。
两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。

解题思路:动态规划

d p ( i ) ( j ) = { d p [ i − 1 ] [ j − 1 ] text1[i]==text2[j] max ⁡ ( d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) text1[i] ≠ text2[j] dp(i)(j)=\begin{cases} dp[i-1][j-1]& \text{text1[i]==text2[j]} \\ \max(dp[i-1][j],dp[i][j-1])& \text{text1[i]$\neq$text2[j]} \end{cases} dp(i)(j)={dp[i1][j1]max(dp[i1][j],dp[i][j1])text1[i]==text2[j]text1[i]=text2[j]

解答
class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        int m=text1.length();
        int n=text2.length();
        vector<vector<int>> dp(m+1,vector<int>(n+1,0));//dp[i][j]表示text1第i个,和text2第j个字符前的最长子序列长度
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                if(text1[i-1]==text2[j-1])dp[i][j]=dp[i-1][j-1]+1;
                else{
                    dp[i][j]=dp[i-1][j]>dp[i][j-1]?dp[i-1][j]:dp[i][j-1];
                }
            }
        }
        return dp[m][n];
    }
};

20210405题号:781. 森林中的兔子

题目描述

森林中,每个兔子都有颜色。其中一些兔子(可能是全部)告诉你还有多少其他的兔子和自己有相同的颜色。我们将这些回答放在 answers 数组里。
返回森林中兔子的最少数量。

解题思路

总数为sum,当数字n第一次出现时sum+n+1
使用数组flag去保存每个数字出现的次数,如果数字出现次数大于了他本身的数字大小,说明至少存在了另一个与之前所有相同数字不一样颜色的兔子,flag置零,flag[n]=0,sum+n+1

解答
class Solution {
public:
    int numRabbits(vector<int>& answers) {
        vector<int> flag(1000,0);
        int n=answers.size();
        int sum=0;
        for(int i=0;i<n;i++){
            if(flag[answers[i]]==0)sum+=answers[i]+1;
            flag[answers[i]]++;
            if(flag[answers[i]]>answers[i]){
                flag[answers[i]]=0;
            }
        }
        return sum;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值