本节,对于我个人而言不只是学会了做这一题,更多的是学到了更多解题技巧,如哈希表,set.count()计数器,substr(字符串下标,字符串长度)字符串数组像整形数组一样多开一个空间,在字符串数组第一个位置留下一个空字符和建立一个vector<bool> bool类型的dp表等。
我们先分析题目要求,像此类查找字符串的问题十分常见。如:在一个较长的字符串中去查找一个单词出现的次数等问题。该问题就是要求找到所有能在字典中找出能够拼接出s字符串的单词,返回true。
首先,动态规划5步走:
1.状态表示:
2.状态转移方程
3.初始化
4.填表顺序
5.返回值
那么一,状态表示:
我们先建立dp[i]表,dp[i]:就表示[0,i]区间内的字符串,能否被字典中的单词拼接而成,能->返回true,不能->就返回false。
二:状态转移方程
首先根据最后一个位置的情况来划分问题,在i位置结束时,dp[i]:就表示[0,i]区间内的字符串,能否被字典中的单词拼接而成,那么在i位置之前与i位置能分成两个模块,即设j为最后一个单词的起始位置。那么在s[j,i]区间就是最后一个单词的区间,在dp[j-1]就是字符串s[0,j-1]位置判断这个字符串能否被字典中的单词拼接。
三:初始化
由于,为了字符串s能与我们填入的下标一一对应,且让字符串从首字符开始就能进入我们的填表环节,那么就将字符串s的首字符置为‘ ’空字符。即s=' '+s;就可以完成字符串的内容往后移动一位,让下标映射关系一一对应。
四:填表顺序:从左往右,五:返回值:是返回字符串在[0,n]区间内,能否被字典中的单词拼接而成,即返回 dp[n];
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
int n=s.size();
set<string> hash;
for(auto s:wordDict)//将字典里的单词都存入hash中,便于查找
hash.insert(s);
vector<bool> dp(n+1);//建立一个bool值的dp表
dp[0]=true;//初始化为true,就不会影响后面的值
s=' '+s;//移动字符串的下标,对应映射关系
for(int i=1;i<=n;i++)
{
for(int j=i;j>=1;j--)//最后一个单词的起始位置
{
if(dp[j-1]&&hash.count(s.substr(j,i-j+1)))//i-j+1,是最后一个单词的长度,在哈希表里面寻找他出现的次数
//最后一个单词的长度慢慢变长,来开始判断
{
dp[i]=true;//只要有一个满足条件就可以结束判断
break;
}
}
}
return dp[n];
}
};
for(auto s:wordDict)//将字典里的单词都存入hash中,便于查找
vector<bool> dp(n+1);//建立一个bool值的dp表
if(dp[j-1]&&hash.count(s.substr(j,i-j+1)))//i-j+1,是最后一个单词的长度,在哈希表里面寻找他出现的次数
//最后一个单词的长度慢慢变长,来开始判断.
该环绕字符串只是多了一个条件从'a'->'z',那么就还时创建dp表,dp[i]表示:以i位置的元素为结尾所有子串里面,有多少个在base中出现过,那么必要条件就是以i位置为结尾
状态转移方程:分两种情况考虑,一就是当长度为1时,就是说明自己的字符绝对在字符串中存在一个子串。当长度大于1时,说明就有要细分,当s[i-1]与s[i]的关系。得出这是dp[i-1]所出现的次数
那么就将dp表初始化为1,就可以不用在填表阶段去考虑长度为1的情况
返回值也是一个难点:并不是返回dp表里所有元素的值,而是要返回已经去掉重复字符串所出现次数的和,就是取以某一个字符为结尾,所包含最大次数的和
class Solution {
public:
int findSubstringInWraproundString(string s) {
int n=s.size();
vector<int> dp(n,1);
for(int i=1;i<n;i++)
{
if(s[i-1]+1==s[i]||s[i-1]=='z'&&s[i]=='a')
{
dp[i]+=dp[i-1];
}
}
vector<int> hash(26);
for(int i=0;i<n;i++)
hash[s[i]-'a']=max(hash[s[i]-'a'],dp[i]);//取出以某一字符为结尾,在字符串中出现最多次的子字符串保留在这个hash数组中
int _max=0;
for(auto e: hash)
_max+=e;
return _max;
}
};
若有不足,欢迎留言~