【问题标题】:Combination Sum Debugging组合和调试
【发布时间】:2020-10-22 10:06:27
【问题描述】:

我已经编写了一些代码来尝试解决这个挑战,但它不起作用,我似乎无法弄清楚哪里出错了,我可以在网上找到答案,但这不是我想要看到的重点为什么我的代码不起作用。

问题:

给定一组候选编号(candidates)(不重复)和一个目标编号(target),找出候选编号总和为target的所有唯一组合。

可以从候选人中无限次选择相同的重复数字。

Input: candidates = [2,3,6,7], target = 7,
A solution set is:
[
  [7],
  [2,2,3]
]

这是我想出的:

class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> res = new ArrayList<>();
        helper(res,new ArrayList<Integer>(), candidates,target,0,0);
        return res;
    }
    //current = current sum, we want it to be target
    //start is index we are at and where the for loop starts

    public void helper(List<List<Integer>> res, List<Integer> temp, int[] nums, int target, int current, int start){
        if(start>=nums.length){
            return;
        }
        if(current>=target){
            if(current==target){
                res.add(new ArrayList<>(temp));
            }
            temp.remove(temp.size()-1);
            helper(res,temp,nums,target,current-nums[start],start+1);
            return;
        }
        for(int i=start; i<nums.length; i++){
            temp.add(nums[i]);
            helper(res,temp,nums,target,current+nums[i],start);
        }
    }
    
}

我的代码解释:

所以我在这里尝试使用递归回溯。我一直循环数组中的一个元素,直到总和 >= target。如果它的 >target 我删除了最后一个元素,因为它使它大于 target 并尝试其他元素。如果它的 = 目标,我将其添加到结果中并删除最后一个元素以尝试查找更多组合。

但显然我在这一行中遇到了错误:

temp.remove(temp.size()-1); //saying index out of bounds i am trying to remove when arraylist is empty

所以它并没有像我想的那样运行,因为如果列表为空,当前应该是 0,它甚至应该进入 if 循环并且永远不应该被删除,但它是,我不知道为什么。

谢谢。

【问题讨论】:

    标签: java arrays recursion backtracking


    【解决方案1】:

    试试这个。

    static List<List<Integer>> combinationSum(int[] candidates, int target) {
        int size = candidates.length;
        List<List<Integer>> result = new ArrayList<>();
        new Object() {
            void search(int index, int sum, List<Integer> selected) {
                if (index >= size) {
                    if (sum == target)
                        result.add(new ArrayList<>(selected));
                } else {
                    int candidate = candidates[index];
                    List<Integer> nextSelected = new ArrayList<>(selected);
                    for (int nextSum = sum; nextSum <= target; nextSum += candidate, nextSelected.add(candidate))
                        search(index + 1, nextSum, nextSelected);
                }
            }
        }.search(0, 0, new ArrayList<>());
        return result;
    }
    

    int[] candidates = {2, 3, 6, 7};
    int target = 7;
    List<List<Integer>> result = combinationSum(candidates, target);
    System.out.println(result);
    

    结果:

    [[7], [2, 2, 3]]
    

    【讨论】:

      【解决方案2】:

      主要问题是尝试回滚当前变量值并在 if(current>=target) if 语句中从那里再次调用辅助方法。您可以使用 for 循环自动为您执行此操作,并在返回后删除添加的数字。然后使用函数 return 更新起始值,使其从您离开的地方继续,从而消除重复。

      因为 for 循环 num[i] 永远不会越界,所以你不必担心

      if(start>=nums.length){
                  return;
              }
      

      这是使用您的解决方法的工作版本

      public static List<List<Integer>> combinationSum(int[] candidates, int target) {
          List<List<Integer>> res = new ArrayList<>();
          helper(res,new ArrayList<Integer>(), candidates,target,0,0);
          return res;
      }
      
      public static int helper(List<List<Integer>> res, List<Integer> temp, int[] nums, int target, int current, int start){
      
          if(current>=target){
                  
              if(current==target){
                  res.add(new ArrayList<>(temp));
              }
              return start + 1;
          }
          for(int i=start; i<nums.length; i++){
              temp.add(nums[i]);
              start = helper(res,temp,nums,target,current+nums[i],start);
              temp.remove(temp.size()-1);
          }
          return start;
      }
      

      运行代码:

      public static void main(String []args){
              List<List<Integer>> res = combinationSum(new int[] {2,3,6,7}, 7);
              System.out.println(res);
      }
      

      结果:

      [[2, 2, 3], [7]]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多