版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_38283262/article/details/84137063
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.
Example
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 between 1 and 12.
- S will consist only of letters or digits.
Solution
我们以abc
为例先把所有可能性化成一棵二叉树:
(abc)
/ \
a(bc) A(bc)
/ \ / \
ab(c) aB(c) Ab(c) AB(c)
/ \ / \ / \ / \
abc abC aBc aBC Abc AbC ABc ABC
可以看出,该树的叶子节点就是abc
转换大小写之后的所有可能性,我们的目标就是找出所有的叶子节点。
广度优先搜索
第一种方式是使用BFS。以输入a1b2
为例,首先把它放入一个队列中。外循环第一次执行时,i指向a
,队列中也只有一个元素a1b2
,这时候将a1b2
出队并且将a1b2
和A1b2
入队;第二次外循环时,i指向的1
是数字,因此直接跳过;第三次外循环时,i指向b
,因为队列中有两个元素因此内循环执行两遍,第一遍先将a1b2
出队并将a1b2
和a1B2
入队,第二遍将A1b2
出队并将A1b2
和A1B2
入队,此时队列中有四个元素a1b2, a1B2, A1b2, A1B2
;第四次外循环时,i指向数字2
,因此直接跳过,循环结束,而此时队列中的元素就是所有的可能性。
public class Solution {
public List<String> letterCasePermutation(String S) {
if(S == null)
return new LinkedList<String>();
Queue<String> queue = new LinkedList<String>();
queue.add(S);
for(int i = 0; i < S.length(); i++) {
if(Character.isDigit(S.charAt(i))) continue;
int size = queue.size();
for(int j = 0; j < size; j++) {
String curr = queue.poll();
char[] chars = curr.toCharArray();
chars[i] = Character.toLowerCase(chars[i]);
queue.add(String.valueOf(chars));
chars[i] = Character.toUpperCase(chars[i]);
queue.add(String.valueOf(chars));
}
}
return new LinkedList<String>(queue);
}
}
深度优先搜索
第二种方式是使用DFS。不像BFS是一层一层的遍历,直到最后一层就是结果,DFS是直接先到达某个叶子节点,将其加入到结果列表中,然后回溯,如此反复。
public class Solution2 {
public List<String> letterCasePermutation(String S) {
if(S == null)
return new LinkedList<String>();
char[] chars = S.toCharArray();
List<String> res = new LinkedList<>();
dfs(res, chars, 0);
return res;
}
private void dfs(List<String> res, char[] chars, int index) {
if(index == chars.length) {
res.add(String.valueOf(chars));
return;
}
if(!Character.isDigit(chars[index])) {
chars[index] = Character.toLowerCase(chars[index]);
dfs(res, chars, index+1);
chars[index] = Character.toUpperCase(chars[index]);
dfs(res, chars, index+1);
} else {
dfs(res, chars, index+1);
return;
}
}
}