题目地址:
https://leetcode.com/problems/letter-case-permutation/
给定一个字符串 s s s,允许将其中的字母大小写变换。返回所有可能性。
思路是DFS。遇到字母时,枚举其为小写和大写两种情况,得到所有可能性等价于在一棵二叉树上进行遍历,只需要记得回溯的时候要恢复现场即可。想象 s s s是树根,变更其第一个英文字母后进入递归下一层,尝试变更之后的英文字母,遍历的时候把沿途经过的所有字符串加入最终结果;在递归结束的时候回溯到上一层节点,此时要把当初变更的字母再变回来,保持搜索树没有发生变化。代码如下:
import java.util.ArrayList;
import java.util.List;
public class Solution {
public List<String> letterCasePermutation(String S) {
List<String> res = new ArrayList<>();
dfs(S.toCharArray(), 0, res);
return res;
}
// 从s[pos]开始枚举每个字母的大小写两个情况
private void dfs(char[] s, int pos, List<String> res) {
// 这里采用先序遍历,一进入树的节点就加入res
res.add(new String(s));
for (int i = pos; i < s.length; i++) {
if (!Character.isLetter(s[i])) {
continue;
}
char ch = s[i];
// 如果当前字母是大写,则将其变为小写,再进入下一层递归;如果当前字母是小写,也类似操作
if (Character.isUpperCase(ch)) {
s[i] = Character.toLowerCase(ch);
dfs(s, i + 1, res);
s[i] = ch;
} else {
s[i] = Character.toUpperCase(ch);
dfs(s, i + 1, res);
s[i] = ch;
}
}
}
}
时间复杂度 O ( n 2 n ) O(n2^n) O(n2n),空间 O ( n ) O(n) O(n)(递归栈深度取决于字符串中的英文字母数量,另外char数组也要占用空间)。