知识拓展练习(经典面试题) / 39. 赎金信
一、题目
给你两个字符串:ransomNote 和 magazine ,判断 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 由小写英文字母组成
四、参考题解
1、方法一:字符统计
题目要求使用字符串 magazine 中的字符来构建新的字符串 ransomNote,且ransomNote 中的每个字符只能使用一次,只需要满足字符串 magazine 中的每个英文字母 (’a’-’z’) 的统计次数都大于等于 ransomNote 中相同字母的统计次数即可。
如果字符串 magazine 的长度小于字符串 ransomNote 的长度,则我们可以肯定 magazine 无法构成 ransomNote,此时直接返回 false。
首先统计 magazine 中每个英文字母 a 的次数 cnt[a],再遍历统计 ransomNote 中每个英文字母的次数,如果发现 ransomNote 中存在某个英文字母 c 的统计次数大于 magazine 中该字母统计次数 cnt[c],则此时我们直接返回 false。
//Java
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
if (ransomNote.length() > magazine.length()) {
return false;
}
int[] cnt = new int[26];
for (char c : magazine.toCharArray()) {
cnt[c - 'a']++;
}
for (char c : ransomNote.toCharArray()) {
cnt[c - 'a']--;
if(cnt[c - 'a'] < 0) {
return false;
}
}
return true;
}
}
复杂度分析
时间复杂度:O(m+n),其中 m 是字符串 ransomNote 的长度,n 是字符串 magazine 的长度,我们只需要遍历两个字符一次即可。
空间复杂度:O(∣S∣),S 是字符集,这道题中 S 为全部小写英语字母,因此 ∣S∣=26。