1178. Number of Valid Words for Each Puzzle Javascript

222 阅读2分钟

Attemp1

思路

匹配所有可能的答案 效率过低

Attempt2 会用位运算符进行优化


代码

/**
 * @param {string[]} words
 * @param {string[]} puzzles
 * @return {number[]}
 */
var findNumOfValidWords = function(words, puzzles) {
    let start = (new Date()).getTime();
    console.log('start');
    let len = puzzles.length;
    let possis = [];
    for(let j = 0; j < len; ++j) {
        let pos = [];
        let first = puzzles[j][0];
        puzzles[j] = puzzles[j].split('').sort();
        let index = puzzles[j].indexOf(first);

        for(let i = 0; i < 128; ++i) {
            let str = i.toString(2).split('');
            if(str[index] !== '1') {
                continue;
            }
            let tmp = '';
            for(let k = 0; k < str.length; ++k) {
                if (str[k] === '1') {
                    tmp += puzzles[j][k];
                }
            }
            pos.push(tmp);
        }
        possis.push(pos); // 预先把可能的答案存储好哦
    }
    let lenW = words.length;
    for(let i = 0; i < lenW; ++i) {
        words[i] = [...new Set(words[i].split(''))].sort().join('');
    }
    console.log('time', (new Date()).getTime() - start)
    let res = [];
    for(let j = 0; j < len; ++j) {
        let count = 0;
        for(let i = 0; i < lenW; ++i) {
            if (possis[j].includes(words[i])) {
                count ++;
            }
        }
        res.push(count);
    }
    console.log('time', (new Date()).getTime() - start)
    return res;
};


Attemp2

思路

通过位运算符处理 解决问题

把字符串转换成一串二进制是数值

例如:aabddc => 00000000000000000000001111

用 Map 存储对应数值


代码


/**
 * @param {string[]} words
 * @param {string[]} puzzles
 * @return {number[]}
 */
var findNumOfValidWords = function(words, puzzles) {
    let ans = [];
    let bit2cnt = new Map();
    for (let i = 0; i < words.length; ++i) {
        let k = 0;
        for(let j = 0; j < words[i].length; ++j) {
            k |= (1 << (words[i][j].charCodeAt(0) - 96));
        }
        let tmp = bit2cnt.get(k) || 0;
        bit2cnt.set(k, tmp + 1)
    }
    
    for(let i = 0; i < puzzles.length; ++i) {
        ans.push(0);
        let k = 0;
        for(let j = 0; j < puzzles[i].length; ++j) {
            k |= (1 << (puzzles[i][j].charCodeAt(0) - 96));
        }
        for(let j = k; j; j = (j - 1) & k) {
            if ((1 << (puzzles[i][0].charCodeAt(0) - 96)) & j)
                ans[i] += (bit2cnt.get(j) || 0);
        }
    }
    return ans;
};


结语

结语是第二天傍晚写下的


Attemp 2 的代码是我直接从一篇 C++ 翻译过来的

原理也大概都懂

光是把字符串 转换成 26 位的二进制数,我的写法就效率极低

从第一天下午开始刷这题,断断续续,一直处于超时的状态

就算知道要用位运算,写出来的效率还是极低

一直持续到第二天早上

我的耐心已经被磨平了

索性直接翻译了


最近几周一直在刷 hard 题

写出来容易

都是不超时难


经历一次这种需要位运算才能 AC 的题


我对位运算处理也没有这么陌生了