「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」。
题目
给你两个字符串: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 <= 105ransomNote和magazine由小写英文字母组成
思考
最近在回顾数据结构方面的题目,比如数组、字符串、队列、二叉树等等。也做了很多动态规划相关的题目,纯粹是学习下解决问题的思想。
这是字符串相关的一道题,难度简单。
我们要判断 ransomNote 能不能由 magazine 里面的字符构成,而且题目中说到了magazine的每个字符只能使用一次。那么,我们可以通过统计每个字符的数量,来解决这个问题。
分以下两种情况:
-
如果字符串
magazine的长度小于字符串ransomNote的长度,则不满足条件。 -
统计字符串
magazine中每个字符出现的次数,再统计字符串ransomNote中每个字符出现的次数,如果ransomNote中某个字符出现的次数大于magazine中该字符出现的次数,则不满足条件,反之满足条件。
解答
方法一:字符统计
/**
* @author: 觅迹
* @param {string} ransomNote
* @param {string} magazine
* @return {boolean}
*/
var canConstruct = function(ransomNote, magazine) {
if (ransomNote.length > magazine.length) {
return false;
}
const cnt = new Array(26).fill(0);
for (const c of magazine) { // 统计magazine中每个字符出现的次数
cnt[c.charCodeAt() - 'a'.charCodeAt()]++;
}
for (const c of ransomNote) { // 比较两个字符串中字符的次数
cnt[c.charCodeAt() - 'a'.charCodeAt()]--;
if(cnt[c.charCodeAt() - 'a'.charCodeAt()] < 0) {
return false;
}
}
return true;
};
复杂度分析
- 时间复杂度:O(m + n),其中 m 和 n 是两个字符串 ransomNote 的长度,我们只需要遍历两个字符串一次。
- 空间复杂度:O(|S|),S 是字符集,这道题中 S 为全部小写英语字母,因此 |S| = 26。