字母大小写全排列
先修知识点
void B(string& A) :函数B的参数是对A的引用,共用同一个内存,返回值直接改变A的值
isalpha(char):函数是用来判断char是不是字母,如果是字母返回true,如果不是字母返回false
题目描述
给定一个字符串S
,通过将字符串S
中的每个字母转变大小写,我们可以获得一个新的字符串。返回所有可能得到的字符串集合。
输入: S = "a1b2" 输出: ["a1b2", "a1B2", "A1b2", "A1B2"]
解题思路
用递归回溯法来完成。(强行记忆吧)
- 先建立字符容器(与函数返回值类型相同):vector<string> letter;
- 在函数中用递归调用进行,递归函数参数分别是字符串 、字符串坐标索引:return backTrack(S,0);
- 在递归回溯函数中,定义函数返回值为vector<string> 与函数一致;递归回溯函数的参数分别为 字符串S,以及当前坐标索引值 index
- 使用递归回溯方法,如下图所示,每次都递归到底,因此先写递归返回条件:判断当前坐标索引值是不是字符串长度,true则将当前字符串S放入字符容器中,并且返回字符容器。if(index==S.size()){letter.push_back(S);return letter;}
- 使用递归需要每次都一深到底,因此直接递归索引+1。backTrace(S,index+1);
- 在递归过程中,判断当前索引的坐标代表的字符是不是字母,如果是的话,将其大小写改变(这里因为ASCⅡ中大写小写字符相差32,用和二进制的32:(1<<5)进行异或比较就可以改变),再次进行深到底的递归调用,存改变之后的S。if(isalpha(S[index])){S[index]^=(1<<5);return backTrace(S,index+1);}
- 如果没有改变,返回当前容器,进入上一层递归。
class Solution {
public:
vector<string> letter;
vector<string> letterCasePermutation(string S)
{
return backTrace(S,0);
}
vector<string> backTrace(string S,int index)
{
if(index==S.size())
{
letter.push_back(S);
return letter;
}
backTrace(S,index+1);
if(isalpha(S[index]))
{
S[index]^=(1<<5);
return backTrace(S,index+1);
}
return letter;
}
};
记忆问题:
- 步骤6(19行代码):不用return,也可以输出结果,可是内存会超。这是为什么呢?
- 这个方法的时间和空间结果都太大(0.1s级和477Mb)