【Leetcode_总结】 784. 字母大小写全排列

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,给其中的字符添加数字。

猜你喜欢

转载自blog.csdn.net/maka_uir/article/details/83151909
今日推荐