使用recusion从列表中获取所有组合,包括使用相同数字的组合

时间:2017-12-11 03:35:48

标签: java recursion

我有一个数字列表:[10, 13, 15]。我试图在列表中找到加起来或小于目标28的数字组合。

目前我有一个递归方法:

    public void combinations(ArrayList<Integer>data,int fromIndex, int endIndex)
{
    int sum = 0;
    int target = 28;
    ArrayList<Integer>results = new ArrayList<Integer>();
    if(fromIndex == endIndex)
    {
        return;
    }

    for(int currentIndex = fromIndex; currentIndex < endIndex; currentIndex++)
    {
        if(sum + data.get(currentIndex) <= target)
        {
            results.add(data.get(currentIndex));
            sum +=data.get(currentIndex);
        }

    }

    System.out.println(results);
    combinations(data, fromIndex + 1, endIndex);
}

目前这个输出: [10, 13],[13, 15],[15]这是正确的,我理解为什么我得到这些解决方案,因为我的递归方法有+1。然而,其他解决方案,如[10],[13],[10,10]等不包括在内,我想知道如何实现这一点,我是否需要在递归方法中更改增量?

1 个答案:

答案 0 :(得分:1)

public static void combinations(ArrayList<Integer> arr, ArrayList<ArrayList<Integer>> ans, int startIndex, int endIndex, int sum) {

    if(startIndex > endIndex) {
        for(ArrayList<Integer> x : ans) {
            System.out.println(x);
        }
        return;
    }
     ArrayList<Integer> newTemp;
    ArrayList<ArrayList<Integer>> newAns = new ArrayList<ArrayList<Integer>>();
    for(ArrayList<Integer> x : ans) {
        newAns.add(x);
    }
    for(ArrayList<Integer> x : ans) {
        int s = 0;
        newTemp = new ArrayList<Integer>();
        for(Integer v : x) {
            newTemp.add(v);
            s+=v;
        }
        if(s + arr.get(startIndex) <= sum) {
            newTemp.add(arr.get(startIndex));
            newAns.add(newTemp);
        }
    }

    if(arr.get(startIndex) <= sum ) {
        newTemp = new ArrayList<Integer>();
        newTemp.add(arr.get(startIndex));
        newAns.add(newTemp);
    }

    combinations(arr,newAns, startIndex+1, endIndex, sum);
}

我必须重写您的代码,因为我无法通过您的代码进行思考。

其次,我必须一直制作一个newArrayList,以避免我第一次面对的ConcurrentModificationException,并在获得一些相关知识后稍后克服。

现在,这个方法应该被称为

public static void main (String[] args) {
    ArrayList<Integer> arr = new ArrayList<Integer>();
    arr.add(10);
    arr.add(15);
    arr.add(13);
    arr.add(-5);
    arr.add(28);
    combinations(arr, new ArrayList<ArrayList<Integer>>(), 0, 4, 28);
}

说明:我已经概括了你的问题的答案,以适应int范围内的任何总和。  我创建了ArrayList的ArrayList,它将打印基本情况下的所有组合。

  1. 我首先添加了一个包含单个元素的ArrayList,即当前元素是&lt; = sum的当前元素。
  2. 然后使用所有剩余的ArrayList,我计算了每个ArrayList的总和,然后检查将当前元素添加到前一个ArrayList中是否保持上述条件。
  3. 同时我在计算每个ArrayList的总和时创建了新的ArrayList并复制了所有元素,然后如果第二种情况保持良好,那么我将当前元素添加到temp ArrayList中,然后将临时ArrayList添加到回答ArrayLists的ArrayList。
  4. 然后我通过将startIndex递增1来调用递归。希望它有所帮助。