【回溯】- LeetCode 17- Medium- 电话号码的字母组合

135 阅读1分钟

题目

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例:

输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

回溯

res = []
def backtrack(path,list):
	if 满足结束条件
    	res.push(path)
    for item of list:
    	do... //做选择
        backtrack(path, list2)
        path.pop() //撤销选择

具体到题目

需要额外用一个变量index记录遍历数字的索引,定义数组path表示选中的项,选择了之后,index+1,list2表示索引+1后的可选择列表。结束条件为path的长度等于输入数字的总长度。

具体代码

// @lc code=start
/**
 * @param {string} digits
 * @return {string[]}
 */
const map = {
  2: ['a', 'b', 'c'],
  3: ['d', 'e', 'f'],
  4: ['g', 'h', 'i'],
  5: ['j', 'k', 'l'],
  6: ['m', 'n', 'o'],
  7: ['p', 'q', 'r', 's'],
  8: ['t', 'u', 'v'],
  9: ['w', 'x', 'y', 'z']
};

var letterCombinations = function (digits) {
  const nums = digits.split('');
  if (!/^[2-9]+$/.test(digits)) {
    return '';
  }
  const res = [];

  const backtrack = (index, path = [], list = []) => {
    if (path.length === nums.length) {
      res.push(path.join(''));
      return;
    }
    for (const char of list) {
      path = [...path, char];
      const nextIndex = index + 1;
      backtrack(nextIndex, path, map[nums[nextIndex]]);
      path.pop();
    }
  };

  backtrack(0, [], map[nums[0]]);
  console.log(res);
  return res;
};

总结

属于嵌套回溯公式的典型做法,需要注意的是引入一个变量记录遍历时的索引。