来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/stickers-to-spell-word
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
[可运行]直观的想法,对于target,我们依次用stickers中的字符串通过剪切去匹配target,方法就是首先看stickers[i]中是否包含target[0](这是一种贪心的想法,如果你没有target[0],我去找下一个字符串,我期望得到可以满足我所有字符的sticker),如果包含,那么把target减去stickers[i]中包含的target的字符的数量,紧接着将其构造为一个新的nowTarget,那么接下来的任务就变成了求nowTarget的最小贴纸数量。任务和子任务的定义是相同的,我们用递归来实现,递归的边界就是完全匹配,也就是nowTarget变为""。
class Solution {
public:
int minStickers(vector<string>& stickers, string target) {
int stickersSize = stickers.size();
//target需要的最少贴纸数量
unordered_map<string, int> strStickerCnt;
//各个贴纸中各个字母出现的次数
vector<vector<int>> myStickers(stickersSize, vector<int>(26, 0));
for (int i = 0; i < stickersSize; ++i)
for (char ch : stickers[i]) myStickers[i][ch - 'a'] += 1;
//初始化,空字符串不需要贴纸
strStickerCnt[""] = 0;
//返回拼凑target需要的最少贴纸数量
return dfs(strStickerCnt, myStickers, target);
}
int dfs(unordered_map<string, int>& strStickerCnt, vector<vector<int>>& myStickers, string target) {
//深搜边界,target已经搜索结束
if (strStickerCnt.count(target)) return strStickerCnt[target];
int minRes = INT_MAX, stickersSize = myStickers.size();
//统计target中各个字符出现的次数
vector<int> tar(26, 0);
for (char ch : target) tar[ch - 'a'] += 1;
//尝试使用每一个sticker
for (int i = 0; i < stickersSize; ++i) {
//当前sticker中没有target[0]这个字符
if (myStickers[i][target[0] - 'a'] == 0) continue;
//nowTarget为使用sticker[i]后剩余的字母
string nowTarget = "";
for (int j = 0; j < 26; j++)
if (tar[j] - myStickers[i][j] > 0)
nowTarget += string(tar[j] - myStickers[i][j], 'a' + j);
//任务转换为搜索nowTarget需要的最少贴纸数
int tempRes = dfs(strStickerCnt, myStickers, nowTarget);
//更新target字符串需要的最少贴纸数
if (tempRes != -1) minRes = min(minRes, 1 + tempRes);
}
//对上一层的反馈,是否找到了一套贴纸方案,是则返回贴纸数目,否则返回-1
strStickerCnt[target] = minRes == INT_MAX ? -1 : minRes;
//for (auto iter = strStickerCnt.begin(); iter != strStickerCnt.end(); ++iter) {
// cout << iter->first << " " << iter->second;
}
cout<<endl;
return strStickerCnt[target];
}
};
我们针对示例一,看一下函数运行的过程:
通过不同层中对strStickerCnt的输出我们可以看到,匹配的过程是:"" 0 -> "ht" 1 -> aeht 2 -> thehat 3
所用到的标签从前往后是:with -> example -> with