给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。

如果可以,返回 true ;否则返回 false 。

magazine 中的每个字符只能在 ransomNote 中使用一次。

function canConstruct(ransomNote: string, magazine: string): boolean {
    const magazineMap = new Map()
    for(const char of magazine){
        if(!magazineMap.get(char)){
            magazineMap.set(char,1)
        }else {
            magazineMap.set(char,magazineMap.get(char)+1)
        }
    }
 
    for(const char of ransomNote){
        if(!magazineMap.has(char)) return false 
        const char_num = magazineMap.get(char)
 
        if(char_num === 1){
            magazineMap.delete(char)
        }else {
            magazineMap.set(char,char_num-1)
        }
    }
 
    return true
};

AI 优化后:直接用 26 长度的数组来作为哈希表,这样能节省空间

function canConstruct(ransomNote: string, magazine: string): boolean {
    if (ransomNote.length > magazine.length) return false;
 
    // 创建一个长度为 26 的数组,记录 a-z 出现的频次
    const charCounts = new Int32Array(26);
    const baseCode = 'a'.charCodeAt(0);
 
    // 统计 magazine 中每个字符的数量
    for (let i = 0; i < magazine.length; i++) {
        charCounts[magazine.charCodeAt(i) - baseCode]++;
    }
 
    // 遍历 ransomNote,减少对应的计数
    for (let i = 0; i < ransomNote.length; i++) {
        const index = ransomNote.charCodeAt(i) - baseCode;
        charCounts[index]--;
        
        // 如果计数小于 0,说明 magazine 里的字符不够用了
        if (charCounts[index] < 0) {
            return false;
        }
    }
 
    return true;
};