LeetCode 算法:T9键盘

351 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 22 天,点击查看活动详情

T9键盘

原题地址

在老式手机上,用户通过数字键盘输入,手机将提供与这些数字相匹配的单词列表。每个数字映射到0至4个字母。给定一个数字序列,实现一个算法来返回匹配单词的列表。你会得到一张含有有效单词的列表。映射如下图所示:

image.png

示例 1:

输入: num = "8733", words = ["tree", "used"]
输出: ["tree", "used"]

示例 2:

输入: num = "2", words = ["a", "b", "c", "d"]
输出: ["a", "b", "c"]

提示:

  • num.length <= 1000
  • words.length <= 500
  • words[i].length == num.length
  • num 中不会出现 0, 1 这两个数字

思路分析

方法一

  1. 首先建立一个字母与数字的对应关系;
  2. 遍历 words,可以得到每个 word 对应的数字,比较得到的数字与 num,若相同,则将该 word 存储到结果集 res 中;
  3. 返回 res 即可。

方法二

  1. 建立一个数字与字母对应关系的数组,为了方便取值,因此将数组的前两项设置为空,也就是数组的下标上所在的位置上的字母为数字与字母的匹配关系;
  2. 遍历 words,对于每个 word 来说,若 num 中对应位置的字母中不包含 word 中的对应下标的字母时,将 flag 置为 false,并跳出循环;
  3. 遍历 word 结束后,flagtrue,则将对应 word 放入结果集 res 中;
  4. 返回 res

方法三

  1. 方法三跟方法二的第一步一样;
  2. 第二步,遍历 words,针对每个 word 使用数组的 every 方法来获取 num 中对应位置的字母中包含 word 中的对应下标的字母,然后将满足条件的放入 res 中。

AC 代码

方法一

/**
 * @param {string} num
 * @param {string[]} words
 * @return {string[]}
 */
var getValidT9Words = function(num, words) {
    const mapWord = {
        a: 2,
        b: 2,
        c: 2,
        d: 3,
        e: 3,
        f: 3,
        g: 4,
        h: 4,
        i: 4,
        j: 5,
        k: 5,
        l: 5,
        m: 6,
        n: 6,
        o: 6,
        p: 7,
        q: 7,
        r: 7,
        s: 7,
        t: 8,
        u: 8,
        v: 8,
        w: 9,
        x: 9,
        y: 9,
        z: 9
    }

    const res = []
    for(let i = 0; i < words.length; i++) {
        const word = words[i].split('').map(a => mapWord[a]).join('')
        if(word === num) {
            res.push(words[i])
        }
    }
    return res
};

结果:

  • 执行结果: 通过
  • 执行用时:96 ms, 在所有 JavaScript 提交中击败了7.79%的用户
  • 内存消耗:48.3 MB, 在所有 JavaScript 提交中击败了11.69%的用户
  • 通过测试用例:33 / 33

方法二

/**
 * @param {string} num
 * @param {string[]} words
 * @return {string[]}
 */
var getValidT9Words = function(num, words) {
     // 建立数字和字母的映射关系
    const mapWord = ['', '', 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqrs', 'tuv', 'wxyz']
    const res = []
    // 设置flag,默认为true
    let flag = true
    for (let i = 0; i < words.length; i++) {
        // 重置flag为true,防止上一个单词为false
        flag = true
        // 当前单词
        const word = words[i]
        for (let j = 0; j < word.length; j++) {
            // 遍历当前单词,判断num相应位置的数字,是否包含相应位置的字母
            if (!mapWord[num[j]].includes(word[j])) {
                // 没包含,flag设置为false,直接退出循环
                flag = false
                break
            }
        }
        // 若包含,放入答案数组
        if(flag) res.push(word)
    }
    return res
};

结果:

  • 执行结果: 通过
  • 执行用时:64 ms, 在所有 JavaScript 提交中击败了84.42%的用户
  • 内存消耗:44.5 MB, 在所有 JavaScript 提交中击败了46.75%的用户
  • 通过测试用例:33 / 33

方法三

/**
 * @param {string} num
 * @param {string[]} words
 * @return {string[]}
 */
var getValidT9Words = function(num, words) {
    const mapWord = ['', '', 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqrs', 'tuv', 'wxyz']
    const res = []
    for (let i = 0; i < words.length; i++) {
        const flag = words[i].split('').every((item, index) => mapWord[num[index]].includes(item))
        if(flag) res.push(words[i])
    }
    return res
};

结果:

  • 执行结果: 通过
  • 执行用时:68 ms, 在所有 JavaScript 提交中击败了72.73%的用户
  • 内存消耗:46.6 MB, 在所有 JavaScript 提交中击败了15.58%的用户
  • 通过测试用例:33 / 33

END