代码随想录二刷 216. 组合总和 III 17. 电话号码的字母组合39. 组合总和

文章提供了三个使用深度优先搜索(DFS)解决组合问题的Go代码示例:组合总和III、电话号码的字母组合和组合总和。这些示例展示了如何通过回溯法找到满足特定条件的所有可能组合。在每个函数中,都使用了路径(path)、结果(res)和当前和(sum)等变量来跟踪和收集解。代码中强调了排序的重要性,以避免重复计算和无效的路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

216. 组合总和 III  

代码如下

var(

    path []int 

    res [][]int 

    sum int 

)

func combinationSum3(k int, n int) [][]int {

              path = make([]int,0)       收集路径上的每一个数 

              res = make([][]int,0)    收集满足条件的结果 

              dfs(k,n,1)        调用函数 

              return res 

}

func dfs(k int,n int , start int) {   start为其实位置

         if len(path) == k &&  sum == n {     如果总和和个数都满足条件进行结果收集 

             tmp := make([]int,len(path))   

             copy(tmp,path)

             res = append(res,tmp)

             return 

          }

          for i := start ; i <= 9 ; i++ {

                   if sum + i > n || 9 - i + 1 < k - len(path) {    如果加上这个数总和大于n或者 9 - i + 1 表示还有几个数可以收集 k - len(path)表示需要收集的数的个数,如果可以收集的个数小于需要收集的个数,则说明要退出该循环,因为无论如何都满足不了条件 

                       break 

                   }

                   path = append(path,i)      收集这个数,更改总和 

                   sum += i 

                   dfs(k,n,i+1)

                   path = path[:len(path)-1]    进行回溯 

                   sum -= i 

          }

}

17. 电话号码的字母组合 

代码如下

var (

    m []string

    path []byte

    res []string

)

func letterCombinations(digits string) []string {

            m = []string{"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"} 先对数字对应的字符串进行收集 

            path = make([]byte,0)

            res = make([]string,0)

            if digits == "" {     如果为空则返回空  

                return nil 

            }

            dfs(digits,0)

            return res 

}

func dfs(digits string , start int) {   start对应的是该字符串每个字符的下标 

         if len(path) == len(digits) {  如果个数满足则进行收集 

            tmp := string(path)  对path进行类型转换

            res = append(res,tmp)

            return 

         }

         digit := int(digits[start] - '0')    取出字符对应的数字 

         str := m[digit-2]                 取出该数字对应的字符 

         for i := 0 ; i < len(str) ; i++ {   遍历字符 

             path = append(path,str[i])

             dfs(digits,start+1)     进行下一层递归,并将下标向后移一位 

             path = path[:len(path)-1]   回溯 

         }

}

39. 组合总和 

代码如下

var (

    path []int 

    res [][]int 

)

func combinationSum(candidates []int, target int) [][]int {

                path = make([]int,0)

                res = make([][]int,0) 

                sort.Ints(candidates)  进行排序 ,为剪枝做准备  

                dfs(candidates,target,0,0)  

                return res 

}

func dfs(candidates []int ,target int , start int, sum int) {

       if  sum == target {

           tmp := make([]int,len(path))

           copy(tmp,path)

           res = append(res,tmp)

           return 

       }

       for i := start ; i < len(candidates) ; i++ {

           if  candidates[i] + sum > target {  如果不进行排序直接进入该行代码的判断,则会出现以下情况,即当前数被重复使用,且大于目标数,而导致比当前数小的但可能满足条件的数直接被跳出循环 例如 目标数是11 ,当前数是8 ,8+8 > 11 所以会直接跳出循环,导致8 之后的数没有得到遍历,所以需要进行排序,保证当前数比之后的数都小,那么如果加上当前数那么还是大于目标数,那么之后的数也肯定大于目标数 

               break 

           }

           path = append(path,candidates[i])

           sum += candidates[i] 

           dfs(candidates,target,i,sum)

           path = path[:len(path)-1]

           sum -= candidates[i]

       }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值