691. 贴纸拼词

691. 贴纸拼词

难度困难40收藏分享切换为英文关注反馈

我们给出了 N 种不同类型的贴纸。每个贴纸上都有一个小写的英文单词。

你希望从自己的贴纸集合中裁剪单个字母并重新排列它们,从而拼写出给定的目标字符串 target

如果你愿意的话,你可以不止一次地使用每一张贴纸,而且每一张贴纸的数量都是无限的。

拼出目标 target 所需的最小贴纸数量是多少?如果任务不可能,则返回 -1。

 

示例 1:

输入:

["with", "example", "science"], "thehat"

输出:

3

解释:

我们可以使用 2 个 "with" 贴纸,和 1 个 "example" 贴纸。
把贴纸上的字母剪下来并重新排列后,就可以形成目标 “thehat“ 了。
此外,这是形成目标字符串所需的最小贴纸数量。

示例 2:

输入:

["notice", "possible"], "basicbasic"

输出:

-1

解释:

我们不能通过剪切给定贴纸的字母来形成目标“basicbasic”。

 

提示:

  • stickers 长度范围是 [1, 50]
  • stickers 由小写英文单词组成(不带撇号)。
  • target 的长度在 [1, 15] 范围内,由小写字母组成。
  • 在所有的测试案例中,所有的单词都是从 1000 个最常见的美国英语单词中随机选取的,目标是两个随机单词的串联。
  • 时间限制可能比平时更具挑战性。预计 50 个贴纸的测试案例平均可在35ms内解决。

 

题目分析:

1. 记忆化搜索。 代码中的一个比较关键的优化点就是会把没有当前target第一个字符的sticker去掉,这样可以减少每个状态所需要计算的sticker数目。

 

class Solution {
public:
    int minStickers(vector<string>& stickers, string target) {
        int stickerSize = stickers.size();
        vector<vector<int>> V(stickerSize, vector<int>(26,0));
        for(int i = 0; i < stickerSize; i++){
            for(int j = 0; j < stickers[i].size(); j++){
                V[i][stickers[i][j] - 'a'] += 1;
            }
        }
        unordered_map<string, int> M; M[""] = 0;
        int ans = DFS(V, M, target);
        if(ans > 20) return - 1;
        return ans;
    }

    int DFS(vector<vector<int>> &V, unordered_map<string, int>& M, string target){
        if(M.find(target) != M.end()){
            return M[target];
        }
        int res = 9999;
        vector<int> tt(26,0);
        for(auto x: target){tt[x-'a'] += 1;}
        for(int i = 0; i < V.size(); i++){
            if(V[i][target[0] - 'a'] == 0) continue;
            else{
                string t = "";
                for(int j = 0; j < 26; j++){
                    if(tt[j] > V[i][j]){
                        t += string(tt[j] - V[i][j], 'a' + j);
                    }
                }
                res = min( res, DFS(V, M, t));              
            }                
        }
        M[target] = res + 1;
        return M[target];
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章