383. Ransom Note

/**
 Given an arbitrary ransom note string and another string containing letters from all the magazines, write a function that will return true if the ransom note can be constructed from the magazines ; otherwise, it will return false.
 
 Each letter in the magazine string can only be used once in your ransom note.
 Note:
 You may assume that both strings contain only lowercase letters.
 
 canConstruct("a", "b") -> false
 canConstruct("aa", "ab") -> false
 canConstruct("aa", "aab") -> true
 */

/**
 Thinking: 
 Ransom <-> Magazine  以下简称为 R  M
 这个题目的意思是 R 可以由 M 构造,而且都是小写字母,这样 M 和 R 里面出现
 的同一个字母 M 的次数要比 R 多才满足。
 于是这个问题就转换了堆排序的基础,给定 26 个小写字母的堆,然后统计 M 里面
 字母出现的次数,然后 R 去匹配,一旦 M 中的某一个堆的数目小于 R 中的,则不
 满足了。
 */

func canConstruct(_ ransom: String, from magazine: String) -> Bool {
    guard ransom.lengthOfBytes(using: .ascii) > 0,
          magazine.lengthOfBytes(using: .ascii) > 0
    else {
        return false
    }
    
    var lowerCaseArray:[Int] = [Int].init(repeating: 0, count: 26)
    
    //注意Swift中的value的获取
    let aValue = ("a" as UnicodeScalar).value
    for ch in magazine.unicodeScalars {
        lowerCaseArray[Int(ch.value - aValue)] += 1
    }
    
    for ch in ransom.unicodeScalars {
        let chValue = Int(ch.value - aValue)
        lowerCaseArray[chValue] -= 1
        //小于零则是无法由当前数目构造
        if (lowerCaseArray[chValue] < 0) {
            return false
        }
    }
    
    return true
}

canConstruct("ab", from: "abc")
canConstruct("", from: "c")
canConstruct("aa", from: "aba")
canConstruct("abc", from: "ab")

你可能感兴趣的:(383. Ransom Note)