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[i−1][j−1]max(dp[i−1][j],dp[i][j−1])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;
}
};