我一直在做HackerRank測試用例,大部分時間我都做得很好,但是我掛斷了一些簡單的例子,當我一直在幫助我時看不到解決方案。我工作的這個問題:Swift中的重構解決方案
https://www.hackerrank.com/challenges/ctci-ransom-note
綁匪寫了勒索信,但擔心它會被追溯至他。他找到了一本雜誌,想知道他是否可以從中刪除全部單詞,並用它來創建一個無法追查的贖金記錄副本。他的筆記中的單詞是區分大小寫的,他必須使用雜誌中的全部單詞,這意味着他不能使用子字符串或連接來創建他需要的單詞。
鑑於雜誌中的文字和贖金筆記中的文字,如果他可以使用雜誌中的全部單詞複製他的贖金筆記,請打印「是」;否則,打印號
輸入格式
第一行包含兩個空間分隔的整數描述的(在該雜誌的字的數目)和(在贖注意到字數)的各個值。 第二行包含空格分隔的字符串,表示存在於雜誌中的單詞。 第三行包含空格分隔的字符串,表示存在於贖金筆記中的單詞。
每個單詞由英文字母(即,to和to)組成。 筆記和雜誌中的文字區分大小寫。 輸出格式
打印是的,如果他可以使用該雜誌創建一個無法追查他的贖金筆記副本;否則,打印號
採樣輸入
6 4
give me one grand today night
give one grand today
樣本輸出
Yes
Explanation
寫勒索信的下落不明副本需要四個詞都出現在雜誌上,所以我們打印是作爲我們的答案。
這裏是我的解決方案:
import Foundation
func main() -> String {
let v = readLine()!.components(separatedBy: " ").map{Int($0)!}
var a = [String](); var b = [String]()
if v[0] < v[1] { return "No"}
for i in 0 ..< 2 {
if i == 0 {
a = (readLine()!).components(separatedBy: " ")
} else { b = (readLine()!).components(separatedBy: " ") }
}
// Get list of elements that intersect in each array
let filtered = Set(a).intersection(Set(b))
// Map set to set of Boolean where true means set a has enough words to satisfy set b's needs
let checkB = filtered.map{ word in reduceSet(b, word: word) <= reduceSet(a, word: word) }
// If mapped set does not contain false, answer is Yes, else No
return !checkB.contains(false) ? "Yes" : "No"
}
func reduceSet(_ a: [String], word: String) -> Int {
return (a.reduce(0){ $0 + ($1 == word ? 1 : 0)})
}
print(main())
我總是在三個20的測試用例與此解決方案的時間了。所以這個解決方案似乎解決了所有的測試案例,但不是在他們所需的時間限制內。這些都是很好的練習,但是當你這樣陷入困境時,這是非常令人沮喪的。
我要指出,我用Sets
和Set(a).intersection(Set(b))
因爲當我試圖映射的Strings
陣列,一半的測試用例超時。
任何更清潔,或更有效的解決方案將不勝感激!謝謝!
你可以使用'基金會'? – Alexander
是的。我總是使用它,實際上 – Pierce
你會想看看'NSCountedSet'。所有你需要做的就是創建一個包含所有需要的單詞(所需消息)的'NSCountedSet',以及所有可用單詞(來自雜誌)的另一個「NSCountedSet」。然後,檢查每一個唯一的單詞,第一組中的計數是否大於第二組中的計數 – Alexander