1.交错字符串 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
给定三个字符串
s1
、s2
、s3
,请判断s3
能不能由s1
和s2
交织(交错) 组成。两个字符串
s
和t
交织 的定义与过程如下,其中每个字符串都会被分割成若干 非空 子字符串:
s = s1 + s2 + ... + sn
t = t1 + t2 + ... + tm
|n - m| <= 1
- 交织 是
s1 + t1 + s2 + t2 + s3 + t3 + ...
或者t1 + s1 + t2 + s2 + t3 + s3 + ...
提示:
a + b
意味着字符串a
和b
连接。示例 1:
输入:s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac" 输出:true示例 2:
输入:s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc" 输出:false示例 3:
输入:s1 = "", s2 = "", s3 = "" 输出:true
class Solution {
public:
bool isInterleave(string s1, string s2, string s3)
{
int n=s1.size();
int m=s2.size();
if(m+n!=s3.size())
return false;
s1=" "+s1;
s2=" "+s2;
s3=" "+s3;
//初始化
vector> dp(n+1,vector(m+1));
dp[0][0]=true;
for(int j=1;j<=m;j++)
{
if(s2[j]==s3[j])
dp[0][j]=true;
else break;
}
for(int i=1;i<=n;i++)
{
if(s1[i]==s3[i])
dp[i][0]=true;
else break;
}
//状态转移方程
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
//两种方法都可
/*if(s1[i]==s3[i+j]&&dp[i-1][j])
{
dp[i][j]=true;
}
else if(s2[j]==s3[i+j]&&dp[i][j-1])
{
dp[i][j]=true;
}*/
dp[i][j]=((dp[i-1][j]&&s1[i]==s3[i+j])||
(dp[i][j-1]&&s2[j]==s3[i+j]));
}
}
return dp[n][m];
}
};
2.两个字符串的最小ASCII删除和 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
给定两个字符串
s1
和s2
,返回 使两个字符串相等所需删除字符的 ASCII 值的最小和 。示例 1:
输入: s1 = "sea", s2 = "eat" 输出: 231 解释: 在 "sea" 中删除 "s" 并将 "s" 的值(115)加入总和。 在 "eat" 中删除 "t" 并将 116 加入总和。 结束时,两个字符串相等,115 + 116 = 231 就是符合条件的最小和。示例 2:
输入: s1 = "delete", s2 = "leet" 输出: 403 解释: 在 "delete" 中删除 "dee" 字符串变成 "let", 将 100[d]+101[e]+101[e] 加入总和。在 "leet" 中删除 "e" 将 101[e] 加入总和。 结束时,两个字符串都等于 "let",结果即为 100+101+101+101 = 403 。 如果改为将两个字符串转换为 "lee" 或 "eet",我们会得到 433 或 417 的结果,比答案更大。
分析:
class Solution {
public:
int minimumDeleteSum(string s1, string s2)
{
int n=s1.size(),m=s2.size();
vector> dp(n+1,vector(m+1));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
if(s1[i-1]==s2[j-1])
{
dp[i][j]=max(dp[i][j],dp[i-1][j-1]+s1[i-1]);
}
}
}
int sum1=0;
int sum2=0;
for(auto sh1:s1) sum1+=sh1;
for(auto sh2:s2) sum2+=sh2;
return sum1+sum2-dp[n][m]*2;
}
};
3.最长重复子数组 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
给两个整数数组
nums1
和nums2
,返回 两个数组中 公共的 、长度最长的子数组的长度 。示例 1:
输入:nums1 = [1,2,3,2,1], nums2 = [3,2,1,4,7] 输出:3 解释:长度最长的公共子数组是 [3,2,1] 。示例 2:
输入:nums1 = [0,0,0,0,0], nums2 = [0,0,0,0,0] 输出:5
class Solution {
public:
int findLength(vector& nums1, vector& nums2)
{
int n=nums1.size();
int m=nums2.size();
vector> dp(n+1,vector(m+1));
int ret=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(nums1[i-1]==nums2[j-1])
{
dp[i][j]=dp[i-1][j-1]+1;
}
else
{
dp[i][j]=0;
}
ret=max(ret,dp[i][j]);
}
}
return ret;
}
};
4.正则表达式匹配 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
给你一个字符串
s
和一个字符规律p
,请你来实现一个支持'.'
和'*'
的正则表达式匹配。
'.'
匹配任意单个字符'*'
匹配零个或多个前面的那一个元素所谓匹配,是要涵盖 整个 字符串
s
的,而不是部分字符串。示例 1:
输入:s = "aa", p = "a" 输出:false 解释:"a" 无法匹配 "aa" 整个字符串。示例 2:
输入:s = "aa", p = "a*" 输出:true 解释:因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。示例 3:
输入:s = "ab", p = ".*" 输出:true 解释:".*" 表示可匹配零个或多个('*')任意字符('.')。
lass Solution {
public:
bool isMatch(string s, string p)
{
int n=s.size();
int m=p.size();
vector> dp(n+1,vector(m+1));
s=" "+s;
p=" "+p;
dp[0][0]=true;
//初始化
for(int i=2;i<=m;i+=2)
{
if(p[i]=='*')
dp[0][i]=true;
else break;
}
for(int i=1;i<=n;i++)
{
//状态转移方程
for(int j=1;j<=m;j++)
{
if(s[i]==p[j]&&dp[i-1][j-1])
dp[i][j]=true;
else if(p[j]=='.'&&dp[i-1][j-1])
dp[i][j]=true;
else if(p[j]=='*')
{
dp[i][j]=dp[i][j-2] || (p[j-1]=='.'||s[i]==p[j-1]) && dp[i-1][j];
}
}
}
return dp[n][m];//返回值
}
};
5.通配符匹配 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
给你一个输入字符串 (
s
) 和一个字符模式 (p
) ,请你实现一个支持'?'
和'*'
匹配规则的通配符匹配:
'?'
可以匹配任何单个字符。'*'
可以匹配任意字符序列(包括空字符序列)。判定匹配成功的充要条件是:字符模式必须能够 完全匹配 输入字符串(而不是部分匹配)。
示例 1:
输入:s = "aa", p = "a" 输出:false 解释:"a" 无法匹配 "aa" 整个字符串。示例 2:
输入:s = "aa", p = "*" 输出:true 解释:'*' 可以匹配任意字符串。示例 3:
输入:s = "cb", p = "?a" 输出:false 解释:'?' 可以匹配 'c', 但第二个 'a' 无法匹配 'b'。
class Solution {
public:
bool isMatch(string s, string p)
{
int n=s.size();
int m=p.size();
vector> dp(n+1,vector(m+1));
dp[0][0]=true;
for(int i=1;i<=m;i++)
{
if(p[i-1]=='*')
dp[0][i]=true;
else break;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(p[j-1]=='*')
{
dp[i][j]=dp[i-1][j]||dp[i][j-1];
}
else
{
if(s[i-1]==p[j-1]&&dp[i-1][j-1])
dp[i][j]=true;
else if(p[j-1]=='?'&&dp[i-1][j-1])
dp[i][j]=true;
}
}
}
return dp[n][m];
}
};