持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情
784. 字母大小写全排列
给定一个字符串 s ,通过将字符串 s 中的每个字母转变大小写,我们可以获得一个新的字符串。
返回 所有可能得到的字符串集合 。以 任意顺序 返回输出。
示例 1:
输入: s = "a1b2"
输出: ["a1b2", "a1B2", "A1b2", "A1B2"]
示例 2:
输入: s = "3z4"
输出: ["3z4","3Z4"]
提示:
1 <= s.length <= 12s由小写英文字母、大写英文字母和数字组成
方法一:直接递归
这道题的官解用了三种方法,涉及广度优先搜索、深度优先搜索(回溯)这些核武器。
但是本题可以不管这些高大上的概念,直接进行最朴素的递归。
解题步骤
● 用递归模拟出所有情况
● 遇到非字母元素,就回溯
● 收集所有到达递归终点的情况,并返回
/**
* @param {string} s
* @return {string[]}
*/
function letterCasePermutation(s) {
const res: string[] = [];
const dfs = (path: string, level: number) => {
while(!/[a-zA-z]/.test(s[level])) {
path += s[level++];
}
if(path.length === s.length) { // 结束当前递归的条件
res.push(path);
return;
}
dfs(path + s[level].toLocaleLowerCase(), level + 1);
dfs(path + s[level].toLocaleUpperCase(), level + 1);
}
dfs('', 0);
return res;
}
方法二:迭代
- 实际每增加一个字母,结果数量 * 2,例如 'a' => ['a', 'A'], 'ab' => {'ab', 'AB', 'Ab', 'aB'}
- 观察 'ab' 的逐位增加规律
['a', 'A']->['a + b', 'a + B', 'A + b', 'A + B'] - 观察 'abc' 的逐位增加规律
['a', 'A']->['a + b', 'a + B', 'A + b', 'A + B']=>['a + b + c', 'a + b + C', 'a + B + c', 'a + B + C', 'A + b + c', 'A + b + C', 'A + B + c' + 'A + B + C'] - 以此类推,观察上面的规律,感觉就很类似二叉树。
- 那么问题就可以变成:遍历二叉树所有可能性,遇到字母复制之前的全部节点,然后拼接大小写即可,非字母直接原样拼接,最终就是我们期望的结果
/**
* @param {string} s
* @return {string[]}
*/
var letterCasePermutation = function (s) {
s = s.toLowerCase()
let arr = [s[0]];
if (s[0].charCodeAt() > 96) arr.push(s[0].toUpperCase())
for (let i = 1; i < s.length; i++) {
arr = arr.map(word => word += s[i])
if (s[i].charCodeAt() > 96) arr = arr.concat(arr.map(word => word.slice(0, -1) + s[i].toUpperCase()))
}
return arr
};