C/C++教程

【回溯】【leetCode高频】:39. 组合总和

本文主要是介绍【回溯】【leetCode高频】:39. 组合总和,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1、题目描述

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。 

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

 

 

 2、算法分析

本题属于回溯算法题型中的组合求和问题,而且数组中的元素可以重复使用。

回溯算法其实就是暴力的递归求解算法。重点的是N叉树的递归思想。子结点到父节点的递归。

 

回溯算法大概有以下几种题型:

组合,排序,子集,切割,棋牌等。

本题是求数组中的组合的和等于target目标值。

注意:组合中的元素可以重复使用。下面分析这道题。

集合存储结果集,path存储单个路径。

 

①回溯函数参数的确定

回溯函数的返回值一般是void,函数名是backTracking(int[] candidates,int target,int sum,int startIndex)

sum代表的是每一个路径的和

startIndex,因为是组合,比如 12 21其实都是一个组合,组合是无序的。设定startIndex是为了去除重复的值。

②递归结束条件

sum > target的时候直接break;

sum == target的时候,说明找到了符合条件的路径,添加进去

③单层搜索

for循环的i要从startIndex开始,因为是去重。

然后将元素添加到path中,sum += candidate[i];

递归,然后回溯。

剪枝操作:

先对数组进行排序,如果发现sum + candidate[i] > target,也就是下一层的元素大于target,那么直接结束循环。

回溯模板:

void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }
 
    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

 3、代码实现

 1 class Solution {
 2     List<List<Integer>> result = new ArrayList<>();
 3     List<Integer> path = new ArrayList<>();
 4         
 5     public List<List<Integer>> combinationSum(int[] candidates, int target) {
 6         Arrays.sort(candidates);
 7         backTracking(candidates,target,0,0);
 8         return result;    
 9     }
10     //回溯函数
11     public void backTracking(int[] candidates,int target,int sum,int start){
12         if(sum > target){
13             return;
14         }
15         if(sum == target){
16             result.add(new ArrayList<>(path));
17             return;
18         }
19         for(int i = start;i < candidates.length;i++){
20             if(sum + candidates[i] > target){
21                 break;
22             }
23             path.add(candidates[i]);
24             sum += candidates[i];
25             // 递归
26             backTracking(candidates,target,sum,i);
27             // 回溯
28             sum -= candidates[i];
29             path.remove(path.size() - 1);
30         }
31 
32     }
33 }

 

这篇关于【回溯】【leetCode高频】:39. 组合总和的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!