691ステッカースペリング
私たちはステッカーのN個の異なる種類を与えています。私たちは、それぞれのステッカー上の小文字の英語の単語を持っています。
あなたは、単一の文字をカットし、与えられたターゲット文字列ターゲットを綴るコレクションから、独自のステッカーを、再配置します。
ご希望の場合は、それぞれの数は無制限でステッカーステッカーあたり複数回使用することができます。
ステッカーの最小数は、対象ターゲットに必要とされているどのくらい綴るするには?タスクが不可能な場合は、-1が返されます。
例1:
入力:
[ "例"、 "と" 、 "科学"]、 "thehat"
出力:
3
説明:
私たちは、ステッカー、および「例」ステッカー「と」2を使用することができます。
ラベル上の文字の後、「thehat」特定のフォームを切り出して再配置されました。
また、これは、ステッカーのターゲット文字列を形成するのに必要な最小数です。
例2:
入力:
[「通知」、「可能性」]、「basicbasic」
输出:
-1
説明:
私たちは、「basicbasic」ターゲットを形成するために、与えられた文字にステッカーをカットすることはできません。
ヒント:
ステッカーの長さの範囲[1、50]。
ステッカー(無アポストロフィ付き)英語の単語を小文字。
範囲[1、15]における標的の長さは、文字を小文字。
すべてのテストケースでは、すべての単語がランダムに選択された1000個の最も一般的なアメリカ英語の単語からあり、目標は2つのランダムな一連の単語です。
時間制限は、通常よりも挑戦する以上であってもよいです。50は、35ミリ秒以内に解決することができます平均ステッカーのテストケースに期待されています。
class Solution {
public int minStickers(String[] stickers, String target) {
int m = stickers.length;
int[][] mp = new int[m][26];
Map<String, Integer> dp = new HashMap<>();
for (int i = 0; i < m; i++)
for (char c : stickers[i].toCharArray()) mp[i][c - 'a']++;
dp.put("", 0);
return helper(dp, mp, target);
}
private int helper(Map<String, Integer> dp, int[][] mp, String target) {
if (dp.containsKey(target)) return dp.get(target);
int ans = Integer.MAX_VALUE, n = mp.length;
int[] tar = new int[26];
for (char c : target.toCharArray()) tar[c - 'a']++;
for (int i = 0; i < n; i++) {
if (mp[i][target.charAt(0) - 'a'] == 0) continue;
StringBuilder sb = new StringBuilder();
for (int j = 0; j < 26; j++) {
if (tar[j] > 0)
for (int k = 0; k < Math.max(0, tar[j] - mp[i][j]); k++)
sb.append((char) ('a' + j));
}
String s = sb.toString();
int tmp = helper(dp, mp, s);
if (tmp != -1) ans = Math.min(ans, 1 + tmp);
}
dp.put(target, ans == Integer.MAX_VALUE ? -1 : ans);
return dp.get(target);
}
}