Leetcode 17:电话号码的字母组合(最详细的解法!!!)

本文详细阐述了如何通过回溯思想解决数字转字母组合问题,包括Python代码实现及优化方法,强调递归与迭代在解决此类问题中的应用。

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

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

**示例:**
输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

说明:
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。

解题思路

这是一个典型的通过回溯思想来解决的问题,其实就是暴力破解。假设我们先输出

a d

接着,我们退回到按2的那一步,也就是回到了(这就是回溯法的精髓,我们要有一步回到上一步的操作,这实际上就是可以通过递归去实现的)

a

我们再进入e,这个时候,我们发现ae的长度等于23的长度,所以,我们将ae添加到结果的result中去。

a e

这里我要说一下,我们常说的回溯法,其实是一种算法思想,而这种算法思想主要通过递归来实现,并不是说两者等同。

class Solution:
    def __init__(self):
        self.letterMap = [
            ' ',
            '',
            'abc',
            'def',
            'ghi',
            'jkl',
            'mno',
            'pqrs',
            'tuv',
            'wxyz'
        ]
    def findCombination(self, digits, index, s, res):
        if index == len(digits):
            res.append(s)
            return 

        char = digits[index]
        letters = self.letterMap[ord(char) - ord('0')]
        for letter in letters:
            self.findCombination(digits, index + 1, s + letter, res)

    def letterCombinations(self, digits):
        """
        :type digits: str
        :rtype: List[str]
        """
        result = list()
        if not digits:
            return result
            
        self.findCombination(digits, 0, "", result)
        return result

一个更pythonic的写法

class Solution:
    def letterCombinations(self, digits):
        """
        :type digits: str
        :rtype: List[str]
        """
        if not digits:
            return []
        
        l_map = {'2':'abc', '3':'def', '4':'ghi', '5':'jkl', 
                 '6':'mno', '7':'pqrs', '8':'tuv', '9':'wxyz'}
        
        chars = [l_map.get(d) for d in digits]
        return [''.join(x) for x in itertools.product(*chars)]

这里我们使用到了itertools.product,实际上表示的是这种操作((x,y) for x in A for y in B)

同样的,对于递归可以解决的问题,我们都应该思考是不是可以通过迭代解决。实际上,我们这里在模拟itertools.product操作。

class Solution:
    def letterCombinations(self, digits):
        """
        :type digits: str
        :rtype: List[str]
        """
        result = list()
        if not digits:
            return result
        
        l_map = {'2':'abc', '3':'def', '4':'ghi', '5':'jkl', 
                 '6':'mno', '7':'pqrs', '8':'tuv', '9':'wxyz'}

        chars = [l_map.get(d) for d in digits]
        tmp = [[]]
        for pool in chars:
            tmp = [x+[y] for x in tmp for y in pool]

        for prod in tmp:
            result.append(''.join(prod))

        return result

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值