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 between1
and12
.S
will consist only of letters or digits.
字母大小写全排列。题意是给一个字符串,请你返回他的大小写全排列,意思是每当遇到其中的字母的时候,需要大写字母有一份,小写字母也有一份。
我这里提供两种做法,一种就是简单的遍历,一种DFS。
首先是遍历。开始遍历input字符串,并且创建一个list of StringBuilder,当遇到数字的时候就直接将数字加入每一个StringBuilder;当遇到字母的时候,需要遍历之前创建过的每一个StringBuilder,并将当前遍历到的字母,大写copy一份,小写也copy一份。
时间O(2^n * n) - n是字符串的长度
空间O(2^n * n)
Java实现
1 class Solution { 2 public ListletterCasePermutation(String S) { 3 List ans = new ArrayList<>(); 4 ans.add(new StringBuilder()); 5 for (char c : S.toCharArray()) { 6 int n = ans.size(); 7 if (Character.isLetter(c)) { 8 for (int i = 0; i < n; i++) { 9 ans.add(new StringBuilder(ans.get(i))); 10 ans.get(i).append(Character.toLowerCase(c)); 11 ans.get(n + i).append(Character.toUpperCase(c)); 12 } 13 } else { 14 for (int i = 0; i < n; i++) { 15 ans.get(i).append(c); 16 } 17 } 18 } 19 List res = new ArrayList<>(); 20 for (StringBuilder sb : ans) { 21 res.add(sb.toString()); 22 } 23 return res; 24 } 25 }
再来是DFS遍历。会在backtracking经典的模板的基础上稍作变化。遇到数字就直接递归到下一层,遇到字母的时候需要用大小写分别递归到下一层。
时间O(2^n * n) - n是字符串的长度
空间O(2^n * n)
Java实现
1 class Solution { 2 public ListletterCasePermutation(String S) { 3 List ans = new ArrayList<>(); 4 backtrack(ans, 0, S.toCharArray()); 5 return ans; 6 } 7 8 public void backtrack(List ans, int i, char[] S) { 9 if (i == S.length) { 10 ans.add(new String(S)); 11 } else { 12 if (Character.isLetter(S[i])) { //If it's letter 13 S[i] = Character.toUpperCase(S[i]); 14 backtrack(ans, i + 1, S); //Upper case branch 15 S[i] = Character.toLowerCase(S[i]); 16 backtrack(ans, i + 1, S); //Lower case branch 17 } else { 18 backtrack(ans, i + 1, S); 19 } 20 } 21 } 22 }
LeetCode 题目总结