目录
题目描述
为了不在赎金信中暴露字迹,从杂志上搜索各个需要的字母,组成单词来表达意思。
给你一个赎金信 (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
。
思路
转自https://leetcode-cn.com/problems/ransom-note/solution/ji-lu-zi-mu-de-chu-xian-ci-shu-bing-bi-j-zksx/
作者:jiang-feng-17
救赎信必须由杂志的内容组成,并且不能重复使用字母。由此可知,每一个字母在救赎信中的出现次数必须小于等于该字母在杂志中出现的次数。
常规情况下使用 HashMap 统计出现次数,字母为 key(键),出现次数为 value(值)。但是本题只有小写字母出现,则可以使用一个长度为 26 的数组代替 HashMap,以达到加速程序的目的。
在参考代码中,使用 0-25 为下标的数组,代替'a'-'z'为 key 的 map。
charCountRN[cc-'a'] 中 [cc-'a'] 是一个数组的下标,需要是一个int整数,cc-'a'即可得到相对应的下标。
举例,'b'对应的0-25中的1,'b'-'a'=1,此处字符之间的减法是计算字符ASCII值的差值。
题解
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
// 新建小写字母频次统计数组,0-25 分别代表 a-z
int[] charCountRN = new int[26];
int[] charCountM = new int[26];
// 将 String 转化成 char[] 可以加速程序,因为 String.charAt() 每次调用都会检查下标是否越界
char[] charArrayRN = ransomNote.toCharArray();
char[] charArrayM = magazine.toCharArray();
// 统计救赎信的各个字母出现次数
for (char c : charArrayRN) {
charCountRN[c-'a']++;
}
// 统计杂志的各个字母出现次数
for (char c : charArrayM) {
charCountM[c-'a']++;
}
// 对每个字母的出现次数进行比较
for (int i = 0; i < 26; i++) {
if(charCountRN[i] > charCountM[i]){
return false;
}
}
return true;
}
}