电话号码组合,公式运算
卡牌分组,归类运算
种花问题,筛选运算
格雷编码,二进制运算

电话号码组合

https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/
image.png

思路:

  • 2个数组,做组合,去拼接

image.png
2,映射 abc
3, 映射 def
输入数字时,把映射的字符 split去做组合

如果是2,3,4,先把2个数组做组合,拿到2,3组合的结果再和 4组合
2个组合成一个数组,进行和下一个数组的组合

  1. const mapNumber = {
  2. 2: 'abc',
  3. 3: 'def',
  4. 4: 'ghi',
  5. 5: 'jkl',
  6. 6: 'mno',
  7. 7: 'pqrs',
  8. 8: 'tuv',
  9. 9: 'wxyz',
  10. };
export function mapTelephone(string) {
  if(!string) return []; // 判断空值

  const mapNumber = {
    2: 'abc',
    3: 'def',
    4: 'ghi',
    5: 'jkl',
    6: 'mno',
    7: 'pqrs',
    8: 'tuv',
    9: 'wxyz',
  };

  // 判断一个值
  if(string.length === 1) {
    const words = mapNumber[string];
    return words ? words.split('') : [];
  }

  // 多个值的逻辑
  // '23' => [2,3] 把输入的字符串 split成数组
  const number = string.split('');

  // [2,3] => ["abc", "def"] 映射后的字母
  const words = number.reduce((memo, key) => {
    if (mapNumber[key]) {
      memo.push(mapNumber[key])
    }
    return memo;
  }, []);

  function combineArray(arr) {
    const [first, last] = arr;
    const temp = [];

    // 如果数组没有第二项,直接返回第一项
    if (!last) return first;

    const {length} = first;
    const {length: subLength} = (last || []);

    // 最外层的循环遍历第一个元素,里面的遍历第二个元素
    for (let i = 0; i < length; i++) {
      const word1 = first[i];
      // 外面循环一次,里面循环 N次
      for (let j = 0; j < subLength; j++) {
        const result = `${word1}${last[j]}`;
        temp.push(result);
      }
    };

    /**
     * 核心步骤
     ["abc", "def", "ghi"],只遍历了前2个,for循环结束后,需要 temp替换前2个
     temp = ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]
     ["abc", "def", "ghi"] => [temp, "ghi"]
     */
    arr.splice(0, 2, temp);

    // 递归调用
    if (last) return combineArray(arr);
  };

  return combineArray(words);
}