突然感觉把回溯当成是地下城迷宫的问题就一下子来感觉了,今天稍微能明白点道理了。哈哈哈。
第二题好绕。
找出所有相加之和为 n
的 k
个数的组合,且满足下列条件:
- 只使用数字1到9
- 每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
var (
res[][]int
path []int
)
func combinationSum3(k int,n int)[][]int{
res,path = make([][]int,0),make([]int,0)
dfs(k,n,1,0)
return res
}
func dfs(k,n,start int,sum int){
if len(path)==k{// 回溯一条边的停止条件,k个元素
if sum ==n{//纳入结果的过滤条件 == n
tmp :=make([]int,k)
copy(tmp,path)
res = append(res,tmp)
}
return
}
for i:= start; i <= 9; i++{
if sum + i > n || 9-i +1 < k-len(path){ break}
path = append(path ,i)//记录本层地下城迷宫的内容路径
dfs(k,n,i+1,sum+i)//从本层下潜到下一层地下城的通关密钥 i+1
path = path[:len(path)-1]//path 作为全局变量,不保存本层的密钥,用于同层其他迷宫的路径保存
}
}
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
var(
m []string
path []byte
res []string
)
func letterCombinations(digits string) []string {
m = []string{"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"}
path,res = make([]byte,0),make([]string,0)
if digits == ""{ return res}
dfs(digits,0)
return res
}
func dfs(digits string,start int){
if len(path)==len(digits){
tmp:=string(path)
res= append(res,tmp)
return
}
digit :=int(digits[start]-'0')
str:=m[digit-2]//因为1是拨号键!!! 所以要去除0,1 ,-2
for j:=0;j<len(str);j++{
path = append(path,str[j])
dfs(digits,start+1)
path = path[:len(path)-1]
}
}