Day134 | 灵神 | 回溯算法 | 子集型 字母大小写全排列
784.字母大小写全排列
思路:
这道题用选或不选的思路来解答。选或不选说的不是选或不选s字符串中的某个字符,而是选或不选改变s字符串中字符的大小写
如果是数字的话就不用说了,我们直接输入到path就行
如果是字母的话,那就有两种情况
1.选择不改变其大小写直接输入到path,这种就是原来什么样子现在还什么样
2.选择改变其大小写直接输入到path,这种就是改变了大小写以后放进去的
需要注意的点:对于同一个结点有多个状态,比如这道题,在选择字母a之后,字母a还有两个状态一个改变大小写一个不改变。如果是这种情况的话就要把两个状态都给列出来,即小写a输入path后递归一遍,大写a输入path后再递归一遍
完整代码:
class Solution {
public:
vector<string> res;
void backtracking(string &s,string path,int i)
{
if(path.size()==s.size())
{
res.push_back(path);
return ;
}
//是数字的话直接选
if(s[i]>='0'&&s[i]<='9')
{
path.push_back(s[i]);
backtracking(s,path,i+1);
path.pop_back();
}
//不是数字的话要分大小写的情况
else
{
//选择不改变原来字符
path.push_back(s[i]);
backtracking(s,path,i+1);
path.pop_back();
//选择改变原来字符
s[i]^=32;
path.push_back(s[i]);
backtracking(s,path,i+1);
s[i]^=32;
path.pop_back();
}
}
vector<string> letterCasePermutation(string s) {
string path;
backtracking(s,path,0);
return res;
}
};
转换大小写的简便写法,大转小小转大一次完成(记住)
^=32
是一个位运算操作,使用按位异或(XOR)来切换字母的大小写:
-
ASCII码基础:
- 在ASCII编码中,大小写字母正好相差32
- 大写字母A-Z:65-90
- 小写字母a-z:97-122
- 二进制表示:大小写字母的第6位不同(从0开始计数)
-
按位异或(XOR)原理:
- XOR运算规则:相同为0,不同为1
a ^= 32
等价于a = a ^ 32
- 32的二进制:
00100000
(只影响第5位)
-
实际效果:
'a' (97) 的二进制: 01100001 XOR 32(00100000) → 01000001 = 65 → 'A' 'A' (65) 的二进制: 01000001 XOR 32(00100000) → 01100001 = 97 → 'a'