力扣新手村第2题:赎金信
原题: 给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以,返回 true ;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。
说在前面: 首先我不明白这个题的题目和题干有什么联系,反正它叫这个就叫这个吧。。。
我发布的答案
/**
* @param {string} ransomNote
* @param {string} magazine
* @return {boolean}
*/
//我理解这道题相当于判断是否是子集
var canConstruct = function (ransomNote, magazine) {
let isSubset = true;
//我们把第一个参数看作是子集,第二个参数看作是父集
// 排序都不是我自己想出来的,是网上突然看到排序, 排序后就简化了很多;
const sonArray = ransomNote?.split('')?.sort();
const parentArray = magazine?.split('').sort();
if (parentArray?.length >= sonArray?.length) {
let i = 0;
while (i < sonArray.length) {
if (sonArray[i] !== parentArray[i]) {
isSubset = false;
}
i++;
}
} else {
isSubset = false;
}
return isSubset;
};
case通过了,但是提交显示解答错误,目前没找到问题所在,哭辽~~
力扣官网答案: (使用26个字母的uniCode编码之间的差值在0-26之间,只需要循环两个字符串就可以了) 发现我热衷于给代码写注释,哈哈哈哈哈哈😂
var canConstruct = function(ransomNote, magazine) {
//如果后者长度小于前者,直接返回false
if (ransomNote.length > magazine.length) {
return false;
}
//创建一个长度为26的数组,并用0填充
const cnt = new Array(26).fill(0);
//一个位置的数字代表一个字母出现的次数,后者++,
for (const c of magazine) {
//Unicode编码之差,以'a'为基准,确定当前的字母在26个字母中的位置;
cnt[c.charCodeAt() - 'a'.charCodeAt()]++;
}
//前者--
for (const c of ransomNote) {
cnt[c.charCodeAt() - 'a'.charCodeAt()]--;
//如果减到有那个位置上的数字为负数,说明后者里面的字母不够用,直接返回false
if(cnt[c.charCodeAt() - 'a'.charCodeAt()] < 0) {
return false;
}
}
return true;
};
时间复杂度O(m+n),m和n分别是两个字符串的长度。
这两天忙着social,又偷懒了,以后再不能偷懒了,菜的要命,还不花时间学习么,小笨蛋~~