[Swift]LeetCode691. 貼紙拼詞 | Stickers to Spell Word

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址: http://www.javashuo.com/article/p-cbnnason-me.html 
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html

We are given N different types of stickers. Each sticker has a lowercase English word on it.git

You would like to spell out the given targetstring by cutting individual letters from your collection of stickers and rearranging them.github

You can use each sticker more than once if you want, and you have infinite quantities of each sticker.數組

What is the minimum number of stickers that you need to spell out the target? If the task is impossible, return -1.微信

Example 1:app

Input:dom

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

Output:函數

Explanation:post

We can use 2 "with" stickers, and 1 "example" sticker.
After cutting and rearrange the letters of those stickers, we can form the target "thehat".
Also, this is the minimum number of stickers necessary to form the target string. 

Example 2:測試

Input:

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

Output:

-1 

Explanation:

We can't form the target "basicbasic" from cutting letters from the given stickers. 

Note:

  • stickers has length in the range [1, 50].
  • stickers consists of lowercase English words (without apostrophes).
  • target has length in the range [1, 15], and consists of lowercase English letters.
  • In all test cases, all words were chosen randomly from the 1000 most common US English words, and the target was chosen as a concatenation of two random words.
  • The time limit may be more challenging than usual. It is expected that a 50 sticker test case can be solved within 35ms on average.

咱們給出了 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內解決。

Runtime: 136 ms
Memory Usage: 20 MB
 1 class Solution {
 2     func minStickers(_ stickers: [String], _ target: String) -> Int {
 3         var N:Int = stickers.count
 4         var freq:[[Int]] = [[Int]](repeating:[Int](repeating:0,count:26),count:N)
 5         var memo:[String:Int] = [String:Int]()
 6         memo[""] = 0
 7         for i in 0..<N
 8         {
 9             for char in stickers[i].characters
10             {
11                 freq[i][char.ascii - 97] += 1
12             }
13         }
14         return helper(&freq, target, &memo)
15     }
16         
17     func helper(_ freq:inout [[Int]], _ target: String,_ memo:inout [String:Int]) -> Int
18     {
19         if let num:Int = memo[target]
20         {
21             return num
22         }       
23         var res:Int = Int.max
24         var N:Int = freq.count
25         var cnt:[Int] = [Int](repeating:0,count:26)
26         for char in target.characters
27         {
28             cnt[char.ascii - 97] += 1
29         }
30         for i in 0..<N
31         {
32             if freq[i][target[0].ascii - 97] == 0
33             {
34                 continue
35             }
36             var t:String = String()
37             for j in 0..<26
38             {
39                 if cnt[j] - freq[i][j] > 0
40                 {
41                     for i in 0..<(cnt[j] - freq[i][j])
42                     {
43                         t.append((97 + j).ASCII)
44                     }
45                     
46                 }
47             }
48             var ans:Int = helper(&freq, t, &memo)
49             if ans != -1 {res = min(res, ans + 1)}
50         }
51         memo[target,default:0] = (res == Int.max) ? -1 : res
52         return memo[target,default:0]
53     }
54 }
55     
56 //String擴展
57 extension String {        
58     //subscript函數能夠檢索數組中的值
59     //直接按照索引方式截取指定索引的字符
60     subscript (_ i: Int) -> Character {
61         //讀取字符
62         get {return self[index(startIndex, offsetBy: i)]}
63     }
64 }
65 
66 //Character擴展 
67 extension Character  
68 {  
69   //Character轉ASCII整數值(定義小寫爲整數值)
70    var ascii: Int {
71        get {
72            return Int(self.unicodeScalars.first?.value ?? 0)
73        }       
74     }    
75 }
76 
77 //Int擴展
78 extension Int
79 {
80     //Int轉Character,ASCII值(定義大寫爲字符值)
81     var ASCII:Character 
82     {
83         get {return Character(UnicodeScalar(self)!)}
84     }
85 }
相關文章
相關標籤/搜索