今日内容:
● 216.组合总和III
● 17.电话号码的字母组合
1. 组合总和III
关联 leetcode 216.组合总和III
-
思路
- 类似 leetcode 77. 组合
- 确定停止条件
- 取到k个元素
- k个元素之和为 目标值
- 取到k个元素
- 剪枝
- 当前的 累加和 已经大于 目标值
-
题解
func combinationSum3(k int, n int) [][]int { rets := make([][]int, 0) ret := make([]int, 0) var backtracking func(targetSum int, k int, sum int, startIdx int) backtracking = func(targetSum int, k int, sum int, startIdx int) { //剪枝操作 if sum > targetSum { return } if len(ret) == k { if targetSum == sum { tmp := make([]int, len(ret)) copy(tmp, ret) rets = append(rets, tmp) } return } // 题目要求:集合里面的数字 1~0,所以这里i最大取到9 for i := startIdx; i <= 9; i++ { sum += i ret = append(ret, i) //中断现场 backtracking(targetSum, k, sum, i+1) //回溯, 恢复到中断现场前的样子 ret = ret[:len(ret)-1] sum -= i } } backtracking(n, k, 0, 1) return rets }
2. 电话号码的字母组合
关联 leetcode 17.电话号码的字母组合
-
思路
- 实现数字和字母的映射
- 使用回溯解决 不定的 for loop次数
- 解决回溯到指定个数字就 return 返回
- 解决 1*# 等异常情况
-
题解
func letterCombinations(digits string) []string { if digits == "" { return []string{} } phoneMap := []string{ // 只存储合法的 数字-字母 映射组合 "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz", } ret := make([]string, 0) //定义回溯算法 //参数: //combination:当前已拼装的字符串 //nextDigits:待遍历的数字键 var backtracking func(combination string, nextDigits string) backtracking = func(combination string, nextDigits string) { if nextDigits == "" {//遍历完所有数字键了,直接返回结果 ret = append(ret, combination) return } letters := phoneMap[nextDigits[0]-'2']//从映射map中取回当前数字键对应的字母集合 for _, letter := range letters { // 这里回溯放在了递归函数里面 // 拼装结果集,遍历下一个字母 backtracking(combination+string(letter), nextDigits[1:]) } } backtracking("", digits) return ret }