算法笔记 -- 383. 赎金信

84 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情

一、题目描述:

383. 赎金信

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

如果可以,返回 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 <= 10^5
  • ransomNote 和 magazine 由小写英文字母组成

二、思路分析:

首先理解题意:判断ransomNote字符串是否由magazine字符串中的字符组成,这里相当于从magazine中拿出若干个或者全部,随意组合。

注意:ransomNote字符串和magazine字符串都是由小写字母组成。

明白题意后,可以分析出这题不需要比较字符串,而是字符的个数,ransomNote字符串中字符··对应的字母··不能多于magazine字符串的。

可以采用索引表,建立长度为26的整型数组,26代表26个字母,数组下标对应字母的ASCII值 a(97)--->0;数组元素的值代表对应字母出现次数。

先统计magazine字符串,在统计ransomNote字符串,统计ransomNote时不需要额外申请数组,在原来的数组上操作就可以。

三、AC 代码:

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        int[] charc = new int[26];
        //字母索引 对应关系:a(97)--->0,b(98)--->1,....
        int mlength = magazine.length();
        int rlength = ransomNote.length();

        if(mlength<rlength) return false;
        
        for(int i = 0;i<mlength;i++){
            ++charc[(magazine.charAt(i)-97)];
            //出现一次,+1
            //magazine.charAt(i)-97 字母ASCII值转化为数组对应下标
            //char和int 做运算后的值为int
        }
        for(int i = 0;i<rlength;i++){
            if((--charc[(ransomNote.charAt(i)-97)])<0){
                /*出现一次,减1,如果小于0,就说明ransomNote字符串中字符··对应的字母··多于
                  magazine字符串的。这时返回false
                */
                return false;
            }
        }
        //没有不符合的情况,返回true;
        return true;
    }
}

范文参考

专C的新人冒险者-新手村任务2 - 赎金信 - 力扣(LeetCode)