持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第32天,点击查看活动详情
题目描述
给定一个字符串 s ,通过将字符串 s 中的每个字母转变大小写,我们可以获得一个新的字符串。
返回 所有可能得到的字符串集合 。以 任意顺序 返回输出。
示例 1:
输入:s = "a1b2"
输出:["a1b2", "a1B2", "A1b2", "A1B2"]
示例 2:
输入: s = "3z4"
输出: ["3z4","3Z4"]
思路分析
- 今天的算法题目字符串类型题目。题目比较清晰,我们可以拆分成两个子问题。一是全排列的问题。二是大小写字母转化的问题。具体到这个问题,频繁修改字符串,我们使用StringBuilder类减少无用对象的创建和使用,提升效率。初始化StringBuilder,然后逐个遍历s的字符,判断是否是字母。如果是大写就转换成小写,然后是小写就转换成大写。当StringBuilder长度与s长度相等时,就是其中一个答案。
- 对于大小写字母转化的问题,这里主要是使用 ASCII 码的知识,其中 'A' 的ASCII的十进制是97,'a' 的ASCII的十进制是65,中间差值是32。利用这一性质,我们就可以实现字符的大小写转化,但是写的稍微有一点冗余。我学习官方题解,可以(char) (s.charAt(pos) ^ 32)这个这样完成大小写转化。为什么呢?比如 A 的ASCII 二进制为 01000010,32的二进制值为 00100000,异或之后,就可以完成转换。
- 具体实现代码如下,供参考。
通过代码
class Solution {
public List<String> letterCasePermutation(String s) {
List<String> ans = new ArrayList<String>();
Queue<StringBuilder> queue = new ArrayDeque<StringBuilder>();
queue.offer(new StringBuilder());
while (!queue.isEmpty()) {
StringBuilder curr = queue.peek();
if (curr.length() == s.length()) {
ans.add(curr.toString());
queue.poll();
} else {
int pos = curr.length();
if (Character.isLetter(s.charAt(pos))) {
StringBuilder next = new StringBuilder(curr);
next.append((char) (s.charAt(pos) ^ 32));
queue.offer(next);
}
curr.append(s.charAt(pos));
}
}
return ans;
}
}
总结
- 今天的题目比较有难度,可以多练习几次。上述算法的时间复杂度是O(2的 n次方),空间复杂度是O(n × 2的 n次方 )
- 坚持算法每日一题,加油!我会继续更新,也欢迎算法爱好者一起交流学习。