LeetCode383.赎金信

303 阅读2分钟

「这是我参与11月更文挑战的第18天,活动详情查看:2021最后一次更文挑战

LeetCode383.赎金信

题目

为了不在赎金信中暴露字迹,从杂志上搜索各个需要的字母,组成单词来表达意思。

给你一个赎金信 (ransomNote) 字符串和一个杂志(magazine)字符串,判断 ransomNote 能不能由 magazines 里面的字符构成。

如果可以构成,返回 true ;否则返回 false 。

magazine 中的每个字符只能在 ransomNote 中使用一次。

示例 1:

  • 输入:ransomNote = "a", magazine = "b"
  • 输出:false

示例 2:

  • 输入:ransomNote = "aa", magazine = "ab"
  • 输出:false

示例 3:

  • 输入:ransomNote = "aa", magazine = "aab"
  • 输出:true

提示:

  • 1 <= ransomNote.length, magazine.length <= 105
  • ransomNote 和 magazine 由小写英文字母组成

解法

本题判断第一个字符串ransom能不能由第二个字符串magazines里面的字符构成,但是这里需要注意两点。第一点“为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思”  这里说明杂志里面的字母不可重复使用。第二点 “你可以假设两个字符串均只含有小写字母。” 说明只有小写字母,这一点很重要因为题目所只有小写字母,那可以采用空间换取时间的哈希策略, 用一个长度为26的数组还记录magazine里字母出现的次数。然后再用ransomNote去验证这个数组是否包含了ransomNote所需要的所有字母。依然是数组在哈希法中的应用,以下是解题流程:

  1. 首先我们利用哈希表,来存储赎金信需要的字符数量
  2. 然后遍历杂志字符串,在哈希表中把需要的数量减一
  3. 最后我们遍历哈希表,如果有字符还没减到0,说明不能满足,返回false
/**
 * @param {string} ransomNote
 * @param {string} magazine
 * @return {boolean}
 */
var canConstruct = function(ransomNote, magazine) {
    let hash={};
    //记录字符空缺
    for(let i=0;i<ransomNote.length;i++){
        let value=ransomNote[i];
        hash[value]?hash[value]++:hash[value]=1;
    }

    //填补空缺
    for(let i=0;i<magazine.length;i++){
        let value=magazine[i];
       if(hash[value]){
           hash[value]--;
       }
    }

    //最后查看哈希表
    for(let key in hash){
        //如果有空缺没填满,则返回false
        if(hash[key]){
            return false;
        }
    }

    return true;

};