Description
Given a string S, we can transform every letter individually to be lowercase or uppercase to create another string. Return a list of all possible strings we could create.
Examples:
Input: S = "a1b2"
Output: ["a1b2", "a1B2", "A1b2", "A1B2"]
Input: S = "3z4"
Output: ["3z4", "3Z4"]
Input: S = "12345"
Output: ["12345"]
Note:
-
S
will be a string with length at most12
. -
S
will consist only of letters or digits.
Solution
DFS, time O(2 ^ k), space ?
自底向上的写法
class Solution {
public List<String> letterCasePermutation(String S) {
return dfsPermutation(S.toLowerCase(), 0);
}
public List<String> dfsPermutation(String s, int start) {
List<String> res = new ArrayList<>();
if (start == s.length()) {
res.add("");
return res;
}
char c = s.charAt(start);
List<String> sub = dfsPermutation(s, start + 1);
for (String permutation : sub) {
res.add(c + permutation);
}
if (Character.isLetter(c)) {
c = Character.toUpperCase(c);
for (String permutation : sub) {
res.add(c + permutation);
}
}
return res;
}
}
DFS, time O(2 ^ k), space O(n)
自顶向下的写法
class Solution {
public List<String> letterCasePermutation(String s) {
if (s == null) {
return Collections.EMPTY_LIST;
}
s = s.toLowerCase();
List<String> res = new ArrayList<>();
StringBuilder sb = new StringBuilder();
dfs(s, 0, sb, res);
return res;
}
public void dfs(String s, int i, StringBuilder sb, List<String> res) {
if (i == s.length()) {
res.add(sb.toString());
return;
}
sb.append(s.charAt(i));
dfs(s, i + 1, sb, res);
if (Character.isLetter(s.charAt(i))) {
sb.setCharAt(i, Character.toUpperCase(s.charAt(i)));
dfs(s, i + 1, sb, res);
}
sb.deleteCharAt(sb.length() - 1);
}
}
Bit-manipulation
注意细节,容易出错。
class Solution {
public List<String> letterCasePermutation(String s) {
s = s.toLowerCase();
List<String> res = new ArrayList<>();
int letterCount = 0;
char[] arr = s.toCharArray();
for (char c : arr) {
if (Character.isLetter(c)) {
++letterCount;
}
}
for (int bits = 0; bits < (1 << letterCount); ++bits) {
StringBuilder sb = new StringBuilder();
int mask = 1 << (letterCount - 1); // important to use a mask!
for (char c : arr) {
if (Character.isLetter(c)) {
if ((bits & mask) == 0) {
sb.append(c);
} else {
sb.append(Character.toUpperCase(c));
}
mask >>= 1; // change mask, not bits
} else {
sb.append(c);
}
}
res.add(sb.toString());
}
return res;
}
}