咱們給出了 N 種不一樣類型的貼紙。每一個貼紙上都有一個小寫的英文單詞。java
你但願從本身的貼紙集合中裁剪單個字母並從新排列它們,從而拼寫出給定的目標字符串 target。app
若是你願意的話,你能夠不止一次地使用每一張貼紙,並且每一張貼紙的數量都是無限的。ide
拼出目標 target 所需的最小貼紙數量是多少?若是任務不可能,則返回 -1。測試
示例 1:ui
輸入:spa
[「with」, 「example」, 「science」], 「thehat」
輸出:code
3
解釋:ci
咱們能夠使用 2 個 「with」 貼紙,和 1 個 「example」 貼紙。
把貼紙上的字母剪下來並從新排列後,就能夠造成目標 「thehat「 了。
此外,這是造成目標字符串所需的最小貼紙數量。
示例 2:字符串
輸入:get
[「notice」, 「possible」], 「basicbasic」
輸出:
-1
解釋:
咱們不能經過剪切給定貼紙的字母來造成目標「basicbasic」。
提示:
stickers 長度範圍是 [1, 50]。
stickers 由小寫英文單詞組成(不帶撇號)。
target 的長度在 [1, 15] 範圍內,由小寫字母組成。
在全部的測試案例中,全部的單詞都是從 1000 個最多見的美國英語單詞中隨機選取的,目標是兩個隨機單詞的串聯。
時間限制可能比平時更具挑戰性。預計 50 個貼紙的測試案例平都可在35ms內解決。
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); } }
咱們給出了 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內解決。
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); } }