递归与回溯:组合总和

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

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

例子:

输入:candidates=[2,3,6,7],target=7

输出:[[2,2,3],[7]]

解释:

2和3可以形成一组候选,2+2+3=7.注意2可以使用多次。

7也是一个候选,7=7

仅有两种组合。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Solution{
 
     List<List<Integer>> res = new ArrayList<>(); // 存储结果
     List<Integer> path = new ArrayList<>(); // 存储路径
 
     public List<List<Integer>> combination(int[] candidates, int target){
        dfs(candidates, 0 , target);
        return res;
     }
     public void dfs(int[] candidates, int u, int target){
        if(target<0){
             return;
        }
        if(target==0){
              res.add(new ArrayList(path));
              return;
        }
        for(int i=u; i<candidates.length; i++){<br>               if(candidates[i] < target){
                  path.add(candidates[i]);
                  dfs(candidates, i, target-candidates[i]); // 因为可以重复使用,所以还是i
                  path.remove(path.size()-1); // 回溯,恢复现场<br>               }
        }
 
     }
 
 
 
 
}

  上面的代码看起来比较简洁,但是在java里一般不提倡定义全局变量,而且这里是局部方法修改全局变量,会让java工程师非常不爽,所以我们还是将其改造成参数的形式。当然代价是代码看起来略显的复杂,其实和上面完全一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Solution{
 
    public List<List<Integer>> combination(int[] candidates, int target){
 
         List<List<Integer>> res = new ArrayList<>();
         List<Integer> path = new ArrayList<>();
         dfs(candidates, 0, path, res);
         return res;
 
 
   }
 
   public void dfs(int[] candidates, int u, int target, List<Integer> path, List<List<Integer>> res){
       if(target < 0) return;
       if(target == 0) {
            res.add(new ArrayList(path));
            return;
       }
       for(int i=u; i<candidates.length; i++){
           if(candidates[i] < target){
               path.add(candidates[i]);
               dfs(candidates, u, target-candidates[i], path, res); // 因为可以重复使用,所以还是i
               path.remove(path.size()-1); // 回溯现场
           }
 
       }
   }
 
 
}

  

 

posted @   樱圃  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示