TypechoJoeTheme

至尊技术网

登录
用户名
密码

golang刷leetcode:统计打字方案数

2025-12-16
/
0 评论
/
2 阅读
/
正在检测是否收录...
12/16

标题:Go语言解LeetCode:优雅处理按键方案统计问题
关键词:Go语言, LeetCode, 动态规划, 组合数学, 字符串处理
描述:本文探讨使用Go语言解决LeetCode 2266题"统计打字方案数"的优雅实现方案,通过动态规划与组合数学的结合处理手机按键映射问题。

正文:
在智能手机普及的今天,我们可能已经忘记了老式按键手机输入文字时的独特体验。LeetCode 2266题"统计打字方案数"正是带我们回到了那个九宫格按键时代。这道题看似简单,却蕴含着巧妙的组合数学思想,今天我们就用Go语言来优雅解决它。

问题场景还原
想象你手握一部老式按键手机:
- 数字键2对应"a","b","c"
- 数字键3对应"d","e","f"
- ...
- 数字键7对应"p","q","r","s"
- 数字键9对应"w","x","y","z"

给定一个数字字符串(如"222"),需要计算可能产生的文字组合数量("aaa","aba","aca"等)。当连续输入相同数字时,每次按键可能选择不同的字符。

算法核心洞察
问题的难点在于处理连续相同数字序列。例如"222":
- 单次按键产生3种可能
- 两次按键产生3×3=9种可能(实际是排列组合)
- 但需考虑按键次数与字符选择的对应关系

我们采用分段处理策略:
1. 将输入字符串按相同数字分段
2. 对每个连续段独立计算组合数
3. 使用乘法原理累计总方案数

Go语言实现
以下是经过优化的Go解决方案:

func countTexts(pressedKeys string) int {
    const mod = 1e9 + 7
    // 建立按键映射表
    keyMap := map[byte]int{
        '2': 3, '3': 3, '4': 3, '5': 3, '6': 3,
        '7': 4, '9': 4,  // 特殊处理7和9
        '8': 3,
    }
    
    dp := make([]int, len(pressedKeys)+1)
    dp[0] = 1  // 空字符串有1种方案
    
    for i := 1; i <= len(pressedKeys); i++ {
        current := pressedKeys[i-1]
        maxStep := keyMap[current]
        
        // 向前回溯处理连续相同数字
        for step := 1; step <= maxStep; step++ {
            if i-step < 0 || pressedKeys[i-step] != current {
                break
            }
            dp[i] = (dp[i] + dp[i-step]) % mod
        }
    }
    
    return dp[len(pressedKeys)]
}

关键代码解析
1. 动态规划数组dpdp[i]表示前i个字符的方案数
2. 按键映射表:特殊处理按键7和9(4个字符)
3. 状态转移:对每个位置i,向前回溯1到maxStep个相同字符
4. 模运算:防止大数溢出,符合题目要求

复杂度分析
- 时间复杂度:O(n*k),其中n为字符串长度,k为最大按键字符数(4)
- 空间复杂度:O(n),动态规划数组开销

边界处理技巧
1. 起始状态:dp[0]=1处理空字符串情况
2. 中断条件:遇到不同字符或超出字符串范围时终止回溯
3. 特殊按键:7和9需要单独处理maxStep=4

实际测试验证
通过LeetCode测试用例验证:
- "222":返回9
- "222222":返回387(验证大数处理)
- "22233":返回36(验证不同字符段组合)

这种解法巧妙地将动态规划与组合数学结合,通过分段处理降低了问题复杂度。在Go语言的简洁语法加持下,我们仅用20行代码就实现了高效解决方案。

通过这道题,我们不仅复习了动态规划的应用技巧,也重温了手机输入法的历史演进。下次遇到类似字符串组合问题,不妨试试这种分段累计的思想,或许能带来意想不到的优雅解法。

朗读
赞(0)
版权属于:

至尊技术网

本文链接:

https://www.zzwws.cn/archives/41538/(转载时请注明本文出处及文章链接)

评论 (0)