持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情
今天的每日一题是784. 字母大小写全排列 - 力扣(LeetCode),看到全排列的题目大概率都是搜索的题目,果然这是一道常见的深度优先搜索和广度优先搜索的题目。
题目
给定一个字符串 s
,通过将字符串 s
中的每个字母转变大小写,我们可以获得一个新的字符串。
问:返回所有可能得到的字符串集合 。以 任意顺序 返回输出。
样例
输入: s = "a1b2"
输出: ["a1b2", "a1B2", "A1b2", "A1B2"]
输入: s = "3z4"
输出: ["3z4","3Z4"]
方法
通过题目可以知道,将对字符中的字母进行大小写替换得到新的字符,最终将不同的字符进行统计。因此我们可以模拟这个过程,通过枚举出所有的字母的变化得到最终的结果。常见的搜索方法都可以解决这道问题,比如深度优先搜索和广度优先搜索,在本题中我们采用深度优先搜索。
深度优先搜索通常由以下部分组成:
- 搜索的结束条件:在搜索时,什么时候结束搜索,并对结果进行判断是否满足条件。在题目中就是当字符中的所有字母被调整后
- 进入下一步搜索的条件:当满足什么条件时,保存当前当前的状态进行进一步的搜索。在题目中就是当找到一个字母时对其进行转变大小写。
- 从之前搜索返回时的恢复操作:当搜索过程回溯时,需要对之前操作的进行还原,这样才能保证所有的情况都可以被搜索到。在题目中对应的就是将之前转变的字母进恢复。
具体的代码总结如下:
public List<String> letterCasePermutation(String s) {
List<String> ans = new ArrayList<>();
dfs(s.toCharArray(), 0, ans);
return ans;
}
public void dfs(char[] arr, int pos, List<String> ans){
// 进入下一步搜索的条件
while (pos < arr.length && Character.isDigit(arr[pos])){
pos++;
}
// 搜索的结束条件
if (pos == arr.length){
ans.add(new String(arr));
return;
}
arr[pos] ^= 32;
dfs(arr, pos + 1, ans);
// 从下一步搜索返回时的恢复操作
arr[pos] ^= 32;
dfs(arr, pos + 1, ans);
}