【赎金信】
初始理解问题
首先,我需要清楚地理解题目要求。题目给出了两个字符串:ransomNote
和 magazine
。我们需要判断是否可以用 magazine
中的字符来构造 ransomNote
。具体来说,magazine
中的每个字符只能使用一次,且必须满足 ransomNote
中每个字符的出现次数不超过 magazine
中对应字符的出现次数。
示例分析
为了更好地理解,我来看几个示例:
-
示例 1:
- ransomNote = “a”, magazine = “b”
ransomNote
需要 1 个 ‘a’,但magazine
中没有 ‘a’,所以返回false
。
-
示例 2:
- ransomNote = “aa”, magazine = “ab”
ransomNote
需要 2 个 ‘a’,但magazine
只有 1 个 ‘a’,所以返回false
。
-
示例 3:
- ransomNote = “aa”, magazine = “aab”
ransomNote
需要 2 个 ‘a’ 和 0 个 ‘b’,magazine
有 2 个 ‘a’ 和 1 个 ‘b’,满足条件,所以返回true
。
解题思路
为了判断 ransomNote
是否可以由 magazine
的字符构成,我们需要:
- 统计
ransomNote
中每个字符的出现次数。 - 统计
magazine
中每个字符的出现次数。 - 比较这两个统计结果:
- 对于
ransomNote
中的每一个字符,magazine
中对应字符的出现次数必须不少于ransomNote
中的。 - 如果有任何一个字符不满足,就返回
false
。 - 如果所有字符都满足,返回
true
。
- 对于
代码实现分析
现在来看给定的代码:
class Solution {
public:bool canConstruct(string ransomNote, string magazine) {int ran[26]={0};int mag[26]={0};for(auto x:ransomNote){ran[x-'a']++;}for(auto x:magazine){mag[x-'a']++;}for(int i=0;i<26;i++){if(ran[i]>mag[i])return false;}return true;}
};
思路
-
初始化计数数组:
int ran[26]={0};
:用于统计ransomNote
中每个小写字母的出现次数,初始化为0。int mag[26]={0};
:用于统计magazine
中每个小写字母的出现次数,初始化为0。
-
统计
ransomNote
的字符频率:for(auto x:ransomNote) { ran[x-'a']++; }
:- 遍历
ransomNote
的每个字符x
。 x - 'a'
将字符转换为 0 到 25 的索引(‘a’ -> 0, ‘b’ -> 1, …, ‘z’ -> 25)。ran[x-'a']++
对应字符的计数加一。
- 遍历
-
统计
magazine
的字符频率:for(auto x:magazine) { mag[x-'a']++; }
:- 同理,遍历
magazine
的每个字符x
。 mag[x-'a']++
对应字符的计数加一。
- 同理,遍历
-
比较两个频率数组:
for(int i=0;i<26;i++) { if(ran[i]>mag[i]) return false; }
:- 对于每个字母(索引 0 到 25):
- 如果
ransomNote
中的该字母数量ran[i]
大于magazine
中的mag[i]
,则无法构造,返回false
。
- 如果
- 如果所有字母都满足
ran[i] <= mag[i]
,则最后返回true
。
- 对于每个字母(索引 0 到 25):
class Solution {
public:bool canConstruct(string ransomNote, string magazine) {int ran[26]={0};int mag[26]={0};for(auto x:ransomNote){ran[x-'a']++;}for(auto x:magazine){mag[x-'a']++;}for(int i=0;i<26;i++){if(ran[i]>mag[i])return false;}return true;}
};