383. 赎金信

383. 赎金信

题目链接
代码随想录

分析

这个题跟 242. 有效的字母异位词 如出一辙,都是通过将字符转化为 ASCII 作为哈希函数来进行从字符到数字的映射,然后在数组对应的位置保存字符出现的次数,key 为字符,value 为字符出现的次数,而且题目中也提示了字符串都是小写字母,因此哈希的结果用一个长度为 26 的 int 数组即可。
然后题目的意思是,magazine 中的每个字符只能在 ransomNote 中使用一次。也就是说,ransomNote 的字符个数,得小于等于 magazine 中的字符个数,很容易想到思路:先统计 magazine 中的字符个数,然后再用减去对应字符在 ransomNote 中的个数,如果没有小于 0 的,就返回 true,如果有,返回 false 。

解题

public boolean canConstruct(String ransomNote, String magazine) {
    int offset = (int)'a';
    char[] sourceCharArr = magazine.toCharArray();
    char[] targetCharArr = ransomNote.toCharArray();
    int[] charCount = new int[26];
    for(int i=0;i<sourceCharArr.length;i++){
        int charIndex = (int)sourceCharArr[i];
        charCount[charIndex-offset]++;
    }
    for(int i=0;i<targetCharArr.length;i++){
        int charIndex = (int)targetCharArr[i];
        charCount[charIndex-offset]--;
    }
    for(int i=0;i<charCount.length;i++){
        if(charCount[i]<0){
            return false;
        }
    }
    return true;
}

也可以直接将两个字符串中的所有的字符都统计出来,然后对比,如果 ransomNote 中某个字符的个数大于 magazine,则可以直接返回 false

public boolean canConstruct(String ransomNote, String magazine) {
    if(ransomNote.length()>magazine.length()){
        return false;
    }
    int[] charTarget = getCharCount( ransomNote.toCharArray());
    int[] sourceTarget = getCharCount( magazine.toCharArray());
    for(int i=0;i<charTarget.length;i++){
        if(charTarget[i]>sourceTarget[i]){
            return false;
        }
    }
    return true;
}

public int[] getCharCount(char[] charArr){
    int offset = (int)'a';
    int[] result = new int[26];
    for(int i=0;i<charArr.length;i++){
        int index = (int)(charArr[i])-offset;
        result[index]++;
    }
    return result;
}

相关题

76. 最小覆盖子串
242. 有效的字母异位词