class Solution {
private:
int dfs(unordered_map<string,int>&dp,vector<vector<int>>&dict,string&target){
int ret=INT_MAX;
if(dp.count(target)){
return dp[target];
}
vector<int>cout(26.0);//target字符串中字符个数
for(auto ch:target){
cout[ch-'a']++;
}
//所有的stickers都要进行判断
for(int i=0;i<dict.size();i++){
if(dict[i][target[0]-'a']==0){
//对于stickers字符串中首字母不相同的字符串先不进行判断,优先挑首字母相同的
continue;
}
string str;//记录对比后剩余还要进行对比的字符串
for(int j=0;j<26;j++){
if(cout[j]>dict[i][j]){
//这个字符有cout[j] - dict[i][j]个剩余的没有匹配完
str += string(cout[j] - dict[i][j],'a'+j);
}
}
int num=dfs(dp,dict,str);//剩下字符进行递归匹配
if(num>=0){
ret=min(ret,num+1);//+1代表了这次循环选了第i张卡片一次,num代表这次匹配后剩下的字符递归后的结果
}
}
if(ret==INT_MAX){
ret=-1;
}
dp[target]=ret;//把这个字符串所用的贴指数记录下来,防止重复遍历
return ret;
}
public:
int minStickers(vector<string>& stickers, string target) {
unordered_map<string,int>dp;//字符串对应最小贴纸数量
dp[""]=0;
int size=stickers.size();
vector<vector<int>>dict(size,vector<int>(26.0));//每一个字符串中字符的个数
for(int i=0;i<size;i++){
for(auto ch:stickers[i]){
dict[i][ch-'a']++;
}
}
return dfs(dp,dict,target);
}
};
LeetCode 贴纸拼词 C++ dfs+dp+剪枝 -注解
该博客介绍了一个使用深度优先搜索(DFS)解决如何用最少数量的贴纸覆盖目标字符串的问题。代码实现中,首先初始化一个字典记录每个贴纸中字符的出现次数,然后通过递归调用DFS函数,对每个可能的贴纸进行尝试,以找到最佳匹配。最终返回的是找到的最小贴纸数量。


被折叠的 条评论
为什么被折叠?



