【问题标题】:How to avoid duplicate lists in List<List<Integer>> in javajava中如何避免List<List<Integer>>中的重复列表
【发布时间】:2018-03-29 04:13:35
【问题描述】:

这样,[2,2,3] & [2,3,2] 两者都不应该出现在其中。

我在代码中所做的是给定一个集合 [2, 3, 6, 7] 和目标 7,我发现候选数字总和为目标的唯一组合

输出:

[

[7],

[2, 2, 3]

] 代码运行良好,但我觉得我通过创建HashSet&lt;ArrayList&lt;Integer&gt;&gt; 使用了一种复杂的方式,使用 Collection.sort() 来避免重复列表。有没有更好的方法可以避免这种情况?

 HashSet<ArrayList<Integer>> set= new HashSet<ArrayList<Integer>>();
        public List<List<Integer>> combinationSum(int[] candidates, int target) {        
            backtract(candidates,target,0, new ArrayList<Integer>(),0);   

            List<List<Integer>> output=new ArrayList<List<Integer>>(set);
            return output;
        }



 public void backtract(int[] candidates, int target, int pos, List<Integer> list, int sum){
        if(sum==target){
            ArrayList l=new ArrayList<Integer>(list);     

            Collections.sort(l);
            set.add(l);
         }

    for(int i=0;i<candidates.length;i++){
        if(sum+candidates[i] > target){
            continue;
        }
        sum=sum+candidates[i];           
        list.add(candidates[i]);
        backtract(candidates,target,i+1, list,sum);
        list.remove(new Integer(candidates[i]));
        sum=sum-candidates[i];
    }
}

【问题讨论】:

  • 使用List&lt;List&lt;Set&gt;&gt;,没什么复杂的,不会添加重复项。
  • 尝试类似子集总和算法

标签: java list sorting arraylist set


【解决方案1】:

这是一种可能的方法。

public static void backtract(int[] candidates, int target, int pos, List<Integer> list, int sum) {
    if(sum == target){
        finalOutput.add(new ArrayList<Integer>(list));
        return;
    }

    for (int i = pos; i < candidates.length; i++) {
        for (int j = 1; j <= (target - sum) / candidates[i]; j++) {
            List<Integer> newList = new ArrayList<>(list);
            for (int k = 0; k < j; k++) {
                newList.add(candidates[i]);
            }
            backtract(candidates, target, i + 1, newList, sum + (candidates[i] * j));
        }
    }
}

这个问题的主要挑战是允许多次拾取特定元素。

所以,这个想法(在上面的代码中)是在每个递归调用中继续前进。在您的代码中,每个递归调用都从索引 0 处的元素开始,这就是导致重复的原因。在这里,每个递归调用都从索引pos 处的元素开始。

要多次选择特定元素,我们通过检查(target - sum) / candidates[i](假设为ct)来检查其中有多少(当前元素)对整体(剩余)目标有贡献。因此,我们通过选择其中的 1、2、3...ct 个(添加到当前总和)来进行递归调用。

几点:

  1. 为了避免改变数组,我创建了新数组以简化代码。如果证明影响性能,您可以更改它。
  2. 我将finalOutput 保留为静态变量。您可以将其作为参数传递。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-21
    • 1970-01-01
    • 2019-08-24
    • 2021-07-16
    • 1970-01-01
    • 2016-08-23
    • 2017-09-30
    • 2021-05-22
    相关资源
    最近更新 更多