0

This question is of combination sum. I tried it through recursion and backtracking but my output is becoming an empty list of lists every time.

public class CombinationSum {

    public static void main(String[] args) {
        int[] candidates = {2,3,6,7};
        System.out.println(combinationSum(candidates,8));
    }

    public static List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> ans = new ArrayList<>();
        List<Integer> currComb = new ArrayList<>();
        getResult(candidates,target,currComb,0,0,ans);
        return ans;
    }

    public static void getResult(int[] candidates,int target, List<Integer> currComb, int currSum, int currIndex,List<List<Integer>> ans) {
        if (currSum > target) {
            return;
        }
        if (currSum == target) {
            ans.add(currComb);
            return;
        }

        for (int i = 0; i < candidates.length ; i++) {
            currComb.add(candidates[i]);
            currSum += candidates[i];
            getResult(candidates, target, currComb, currSum, i, ans);
            currComb.remove(currComb.size() -1);
            currSum -= candidates[i];
        }
    }
}
Ted Klein Bergman
  • 9,146
  • 4
  • 29
  • 50
  • When you use a debugger, what is the *first* thing this does wrong? – Scott Hunter Feb 17 '22 at 19:01
  • Is this C# or Java? You didn't tag it. – Tim Roberts Feb 17 '22 at 19:02
  • @TimRoberts `System.out.println` seems like java – derpirscher Feb 17 '22 at 19:03
  • You are always operating on the very same inner list and never create a new one. Thus all your `currComb.add()` and `currComb.remove()` is in fact operating on the very same list. – derpirscher Feb 17 '22 at 19:06
  • 1
    Remember that `ans.add(currComb)` does not make a COPY of the list. You only allocate two lists in this entire program. The first list (`ans`) is going to end up containing many references to the other list (`currComb`). Every time you change `currComb`, you change all the lists in `ans`. – Tim Roberts Feb 17 '22 at 19:06
  • 1
    What is "combination sum" *supposed* to do? – Scott Hunter Feb 17 '22 at 19:30
  • In addition to what @TimRoberts said, `getResult` takes a parameter `currIndex` which it never uses. It should be the starting offset of the `for` loop, right? – David Conrad Feb 17 '22 at 20:40

1 Answers1

0

There are some things that are wrong with this code of yours.

ans.add(currComb);

This would always give you the wrong result even if your code was right. List is a reference type in Java so you should always add a new instance of list in your answer. For example

ans.add(new ArrayList(currComb));

You are passing in currIndex but you are not using it. You probably need to call your recursive function twice to simulate whether or not you are adding it to your list.

I solved this question last night on LeetCode. This was my code and it worked for me.

class Solution {
    public List<List<Integer>> combinationSum(int[] nums, int target) {
        List<List<Integer>> res = new ArrayList();
        if(nums == null || nums.length == 0) {
            return res;
        }
        dfs(res, nums, 0,target, new ArrayList());
        return res;
    }
    public void dfs(List<List<Integer>> res, int[] nums, int i, int target, List<Integer> temp) {
        if(target == 0) {
            res.add(new ArrayList<>(temp));
            return;
        }
        if(target < 0 || i >= nums.length) {
            return;
        }
        
        temp.add(nums[i]);
        dfs(res, nums, i, target - nums[i], temp);
        temp.remove(temp.size() - 1);
        dfs(res, nums, i+1, target, temp);
    }
}
Aditya
  • 175
  • 9