# 题目
给你两个字符串: ransomNote
和 magazine
,判断 ransomNote
能不能由 magazine
里面的字符构成。
如果可以,返回 true ;否则返回 false 。
magazine
中的每个字符只能在 ransomNote
中使用一次。
# 自己解题
拿到题略一思考,可以将 magazine
转为数组,然后循环 ransomNote
的每一个字符,判断是否在数组里即可,每次循环需将查找到的字符串从数组里去掉,还是挺简单的.
function canConstruct(ransomNote: string, magazine: string): boolean { | |
let arr = magazine.split(""); | |
for(let i = 0;i<ransomNote.length;i++){ | |
let str_index = arr.findIndex( v => v === ransomNote[i]); | |
if(str_index > -1){ | |
arr.splice(str_index,1); | |
}else{ | |
return false; | |
} | |
} | |
return true; | |
}; |
提交,执行用时: 316 ms , 在所有 TypeScript 提交中击败了 11.07% 的用户.
说明还是有很大的优化空间.
# 学习解法
还可以使用 Map
, 先循环 ransomNote
, 将每个字符出现的次数作为 value
, 字符作为 key
, 再循环 magazine
, 出现该字符的话,把 value
减 1, 最后判断 Map
中是否存在 value
为正的情况,为正则返回 false
function canConstruct(ransomNote: string, magazine: string): boolean { | |
let map=new Map(); | |
for(let item of ransomNote){ | |
if(!map.has(item)){ | |
map.set(item,1); | |
}else{ | |
map.set(item,map.get(item)+1); | |
} | |
} | |
for(let item of magazine){ | |
if(map.get(item)>0){ | |
map.set(item,map.get(item)-1); | |
} | |
} | |
for(let item of ransomNote){ | |
if(map.get(item)>0){ | |
return false; | |
} | |
} | |
return true; | |
}; |
代码比较多,提交测试一下,执行用时: 76 ms , 在所有 TypeScript 提交中击败了 78.97% 的用户,快了 3 倍以上,以后遇到这种题还是要多考虑 Map
Set
多一点.