LeetCode 17*/46*. 电话号码的字母组合/全排列(回溯法)(Python)

简介: 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。



给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。


20191221143021265.png


示例:


输入:"23"

输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

思路:暴力破解,回溯法


利用树形结构如图  

20191221143134192.png


将digits数组中每一位数字对应的字母依次取出来,再加上后面位置的数字所代表的的所有字母依次递归。


class Solution:
    res = []
    letterMap = {
        "0": " ",
        "1": "",
        "2": "abc",
        "3": "def",
        "4": "ghi",
        "5": "jkl",
        "6": "mno",
        "7": "pqrs",
        "8": "tuv",
        "9": "wxyz",
    }
    def letterCombinations(self, digits: str) -> List[str]:
        # 一定要清除成员变量,否则下个测试用例中会有上一次的结果
        self.res = []
        if digits == "":
            return self.res
        self.findCombination(digits, 0, "")
        return self.res
    # s中保存此时从digits[0...index-1]数字组合中得到的一个字符串
    # 将digits[index]对应的字母添加到s中
    def findCombination(self, digits: str, index: int, s: str):
        if index == len(digits):
            self.res.append(s)
            return
        num = digits[index]
        letters = self.letterMap[num]
        for l in letters:
            self.findCombination(digits, index + 1, s + l)
        return
 这里使用了类的成员变量来存储最后的结果,注意一定要有 self.res = [] 这一步,否则leetcode上测试的前一个计算结果会保存下来影响后面的判断
给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]
思路:和第17题类似,都采用回溯法,代码整体框架不变,需要注意:
① 上一题中数字的顺序不变,例如[2, 3, 4],最后的结果就是输出2,3,4所代表的字母的排列,而本题意思是结果中可能含有[4,3,2]......,所以数字顺序可变,因此需要另外一个数组used记录已经使用过的数字
② 使用回溯法时,递归出来之后要注意及时回复状态,例如从[1,2,3]出来,返回到[1,2,X]时,需要将3这个数字在used中重新记为未使用过,并将[1,2,3]变为[1,2],此题更能体现回溯思想
python中深拷贝浅拷贝的问题。。。坑了我10分钟的时间调试
class Solution:
    res = []
    used = []
    def permute(self, nums: List[int]) -> List[List[int]]:
        self.res = []
        self.used = [0 for _ in nums]
        if len(nums) == 0:
            return []
        p = []
        self.generatePermutation(nums, 0, p)
        return self.res
    def generatePermutation(self, nums: List[int], index: int, p: List[int]):
        if index == len(nums):
            self.res.append(p.copy())   # 深复制,浅复制,好坑啊~~
            return
        for i in range(len(nums)):
            if self.used[i] == 0:
                p.append(nums[i])
                self.used[i] = 1
                self.generatePermutation(nums, index + 1, p)
                # 回溯到上一状态
                p.pop()
                self.used[i] = 0
        return


这里使用了类的成员变量来存储最后的结果,注意一定要有 self.res = [] 这一步,否则leetcode上测试的前一个计算结果会保存下来影响后面的判断


给定一个没有重复数字的序列,返回其所有可能的全排列。


示例:


输入: [1,2,3]

输出:

[

 [1,2,3],

 [1,3,2],

 [2,1,3],

 [2,3,1],

 [3,1,2],

 [3,2,1]

]


思路:


和第17题类似,都采用回溯法,代码整体框架不变,需要注意:


① 上一题中数字的顺序不变,例如[2, 3, 4],最后的结果就是输出2,3,4所代表的字母的排列,而本题意思是结果中可能含有[4,3,2]......,所以数字顺序可变,因此需要另外一个数组used记录已经使用过的数字


② 使用回溯法时,递归出来之后要注意及时回复状态,例如从[1,2,3]出来,返回到[1,2,X]时,需要将3这个数字在used中重新记为未使用过,并将[1,2,3]变为[1,2],此题更能体现回溯思想


class Solution:
    res = []
    used = []
    def permute(self, nums: List[int]) -> List[List[int]]:
        self.res = []
        self.used = [0 for _ in nums]
        if len(nums) == 0:
            return []
        p = []
        self.generatePermutation(nums, 0, p)
        return self.res
    def generatePermutation(self, nums: List[int], index: int, p: List[int]):
        if index == len(nums):
            self.res.append(p.copy())   # 深复制,浅复制,好坑啊~~
            return
        for i in range(len(nums)):
            if self.used[i] == 0:
                p.append(nums[i])
                self.used[i] = 1
                self.generatePermutation(nums, index + 1, p)
                # 回溯到上一状态
                 p.pop()
                self.used[i] = 0
        return



相关文章
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
356 6
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
10月前
|
存储 算法 Go
【LeetCode 热题100】17:电话号码的字母组合(详细解析)(Go语言版)
LeetCode 17题解题思路采用回溯算法,通过递归构建所有可能的组合。关键点包括:每位数字对应多个字母,依次尝试;递归构建下一个字符;递归出口为组合长度等于输入数字长度。Go语言实现中,使用map存储数字到字母的映射,通过回溯函数递归生成组合。时间复杂度为O(3^n * 4^m),空间复杂度为O(n)。类似题目包括括号生成、组合、全排列等。掌握回溯法的核心思想,能够解决多种排列组合问题。
411 11
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
451 2
|
算法
Leetcode第46题(全排列)
这篇文章介绍了LeetCode第46题“全排列”的解题方法,使用深度优先搜索(DFS)和回溯算法来生成给定数组的所有可能排列。
267 0
Leetcode第46题(全排列)
|
算法
Leetcode第十七题(电话号码的字母组合)
这篇文章介绍了如何使用深度优先搜索(DFS)算法来解决LeetCode第17题——电话号码的字母组合问题,通过递归方法生成所有可能的字母组合。
189 0
Leetcode第十七题(电话号码的字母组合)
|
算法
【LeetCode 52】17.电话号码的字母组合
【LeetCode 52】17.电话号码的字母组合
175 0
Leetcode第47题(全排列II)
LeetCode第47题要求返回一个包含重复数字序列的所有不重复全排列,通过深度优先搜索和去重策略来解决。
131 0
LeetCode第46题全排列
LeetCode第46题"全排列"的解题方法,利用回溯法避免重复并确保元素的有序性,生成所有可能的排列组合。
LeetCode第46题全排列
LeetCode第17题电话号码的字母组合
该文章介绍了 LeetCode 第 17 题电话号码的字母组合的解法,通过分析得出可使用递归和回溯的思想解决,避免循环穷举的高循环次数,并给出了具体的编码实现,同时总结了该题较难理解,需要了解递归的本质,当嵌套循环层次多时可考虑递归。
LeetCode第17题电话号码的字母组合
|
Python
【Leetcode刷题Python】50. Pow(x, n)
本文介绍了LeetCode第50题"Pow(x, n)"的解法,题目要求实现计算x的n次幂的函数,文章提供了递归分治法的详细解析和Python实现代码。
351 1

热门文章

最新文章

推荐镜像

更多