Q:
给定一个字符串S
,通过将字符串S
中的每个字母转变大小写,我们可以获得一个新的字符串。返回所有可能得到的字符串集合。
示例:
输入: S = "a1b2"
输出: ["a1b2", "a1B2", "A1b2", "A1B2"]
输入: S = "3z4" 输出: ["3z4", "3Z4"]
输入: S = "12345" 输出: ["12345"]
注意:
S
的长度不超过12
。S
仅由数字和字母组成。
思路:首先考虑到是排列问题 还是希望通过递归来完成,虽然递归不一定是最快解决问题的。其次题目是一个树状结构
为啥是树状呢,因为对于每一个字母有两个大小写,因此往下遍历的时候均有两条路可以选择,整体就像一个二叉数,因此选择递归中的回溯算法,代码如下:
class Solution(object):
def letterCasePermutation(self, S):
"""
:type S: str
:rtype: List[str]
"""
res = []
self.backtrack(S,0,res)
return res
def backtrack(self,s,i,res):
if i == len(s):
res.append(s)
return
self.backtrack(s,i+1,res)
if s[i] > '9':
if s[i].isupper():
s = s[:i]+ s[i].lower()+s[i+1:]
else:
s = s[:i] + s[i].upper() + s[i+1:]
self.backtrack(s, i + 1, res)
backtrack(s,i,res) s表示字符串,判定边界i为 i == len(s) 时候结束当前函数调用 i == len(s)表示遍历到树的叶子节点,结果保存在res中,返回父节点。否者继续递归,此时 i+=1,表示遍历下一个节点。之前使用了str中的replace函数,问题是replace会将字符串中所有的旧字符换为新的字符,因此使用了字符串相加的形式 s = s[:i]+ s[i].lower()+s[i+1:] 看看之后能不能有更好的解决办法,做字符串替换,还有就是注意下标 s[i+1:] 到最后 而不是s[i] 。同时学习到几个函数 isupper() 判断是否是大写 同时 islower() ,isdigit() 判断是否是数字 lower() 转换为小写 upper() 大写,或者chr(ord(s[i])+32)这种方法也可以实现大小写转换。
整个回溯的过程如下图所示:
显然递归的办法不是时间最快的解决方法,因此还可以参考时间最短的AC记录:
class Solution(object):
def letterCasePermutation(self, S):
"""
:type S: str
:rtype: List[str]
"""
res = [""]
for s in S:
if not s.isalpha():
for i in range(len(res)):
res[i] += s
else:
for i in range(len(res)):
tmp = res[i]
res[i] += s.lower()
res.append(tmp+s.upper())
return res
这个求解方式将字符与数字分开,先将字母的大小写形式保存,再遍历res,给其中的字符添加数字。