# 题目
给你两个字符串: 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 多一点.
