LeetCode(383.赎金信)

给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。

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

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

示例

输入:ransomNote = "a", magazine = "b"

输出:false

示例 2:

输入:ransomNote = "aa", magazine = "ab"

输出:false

示例 3:

输入:ransomNote = "aa", magazine = "aab"

输出:true

 

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ransom-note
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

第一次遇到这种解决方式(个人理解,若有错误,欢迎指正,谢谢!!)

/**
 * @param {string} ransomNote
 * @param {string} magazine
 * @return {boolean}
 */
var canConstruct = function(ransomNote, magazine) {
    //哈希解法
    //用一个长度为26的数组还记录magazine里字母出现的次数。
    //然后再用ransomNote去验证这个数组是否包含了ransomNote所需要的所有字母。
    const strArr = new Array(26).fill(0), 
        base = "a".charCodeAt();//返回字符串第一个字符的 Unicode 编码(H 的 Unicode 值)
    for(const s of magazine) {
        strArr[s.charCodeAt() - base]++;
        //记录magazine里的元素出现的次数。strArr是26个字母,起始的次数全是零
        //假如出现一次b,那么就在b的编码减去a的编码的数字为下标的地方加一,表示b出现过一次
        //同理,其他元素出现也是在该元素的编码减去a的编码的数字为下标来计数
        //s则是用来遍历magazine里的每个字母
    }
    for(const s of ransomNote) {
        const index = s.charCodeAt() - base;
        //index是用来寻找ransomNote中当前字母在strArr中对应的下标
        if(!strArr[index]) return false;
        //如果,当前字母的次数不存在了,那么久说明ransomNote里的元素不能组成magazine
        strArr[index]--;
        //否则就将次数减一
    }
    return true;
};

其中关键的思路就是将字母转换为在26个字母相对应的位置进行计数。

记录a的编码,然后再其他字母转化为编码时,减去a的编码,就可以在以当前数字为下标的数组中记录一次出现的次数。当这个字符串遍历结束且计数结束,就可以去遍历下一个字符串。将当前字符串的次数用上一个字符串的次数减一来计算,这样加入当前字符串的某个元素在上次字符串的计数中次数为零,就证明上一个字符串无法组成当前的字符串。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值