给定一个字符串S
,通过将字符串S
中的每个字母转变大小写,我们可以获得一个新的字符串。返回所有可能得到的字符串集合。
示例:
输入: S = "a1b2"
输出: ["a1b2", "a1B2", "A1b2", "A1B2"]
输入: S = "3z4"
输出: ["3z4", "3Z4"]
输入: S = "12345"
输出: ["12345"]
注意:
S
的长度不超过12
。S
仅由数字和字母组成。
思路:这道题用递归,但是要注意递归的时候有个小技巧,由于输入的字符串中只有字母和数字,小写字母的ascll码范围是:97~122,大写字母的ascll码范围是:65~90,数字字符的范围是:49~57。观察到数字字符的ascll码比字母都要小而且小写字母比对应的大写字母大32,刚好是2的32次方,所以相当于小写字母的二进制表示ascll码从右往左的第6位由0变成1就变成了对应的大写字母(这方法真是巧!!!),同理对于大写字母把第六位的1变成0就是大写向小写的转换,这个过程可以用S[i]^32来完成。
参考代码:
class Solution {
public:
void letterCasePermutationCore(string &S,int n, vector<string> &res) {
if (n == S.size()) {
res.push_back(S);
return;
}
if (S[n] > '9') {
letterCasePermutationCore(S, n + 1, res);
S[n] = S[n] ^ 32;
letterCasePermutationCore(S, n + 1, res);
S[n] = S[n] ^ 32;
}
else {
letterCasePermutationCore(S, n + 1, res);
}
}
vector<string> letterCasePermutation(string S) {
if (S.size() == 0) return { "" };
vector<string> res;
letterCasePermutationCore(S, 0, res);
return res;
}
};
思路二:这道题还有可以采用循环的方法来做,比如输入"a2bd",首先初始化res为""。
对于第一个字符'a',放入res中,res为['a','A']
对于第二个字符'2',放入res中,res为['a2','A2']
对于第三个字符'b',放入res中,res为['a2b','A2b','a2B','A2B']
对于第四个字符'd',放入res中,res为['a2bd','A2bd','A2Bd','A2Bd','a2bD','A2bD','A2BD','A2BD']
可以看到,每次都把原来的数组扩大两倍,然后加入新的字符的大写,原来的数组加入新的字符的小写
参考代码:
class Solution {
public:
vector<string> letterCasePermutation(string S) {
vector<string> res{ "" };
for (auto c : S) {
int len = res.size();
if (c >= '0' && c <= '9') {
for (int i = 0; i < len;i++) {
res[i].push_back(c);
}
}
else {
for (int i = 0; i < len;i++) {
res.push_back(res[i]);
res[i].push_back(tolower(c));
res[i + len].push_back(toupper(c));
}
}
}
return res;
}
};