【问题标题】:How to create all possible subsets of size k from an array of size n (no repeats)?如何从大小为 n 的数组中创建所有可能的大小为 k 的子集(不重复)?
【发布时间】:2015-12-06 02:49:35
【问题描述】:

所以我有一个双打数组。我想在这个大小为 k 的数组中找到一个子集,并将所有不在子集中的子集存储到不同的子数组中。我想对所有可能的子集执行此操作,而无需重复。

最好的方法是什么?

double[] sample = {
  1.0, 3.0, 1.6, 2.1, 2.5, 2.7, 2.3, 1.5, 1.1, 0.5, 2.0, 2.0, 1.2, 1.2, 1.3, 0.5, 1.4, 2.4
};

public static void main(String[] args) {
  ArrayList < double[] > list = new ArrayList < double[] > ();
  double[] noo = pickNRandom(sample);
  if (!list.contains(noob)) { //here I want to make sure that it is a unique   subset
    list.add(noob);
    for (double a: noob) {
      System.out.print(a + " ");
    }
    System.out.println("");
  }
}

public static double[] pickNRandom(double[] lst) { //finding a random subset
  double[] i = lst;
  Collections.shuffle(Arrays.asList(i));
  double[] fin = {
    i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]
  };
  return fin;
}

【问题讨论】:

标签: java permutation


【解决方案1】:

我会推荐两种可能的方法来解决这个问题,这是子集和问题的一种变体(一个不能在多项式时间内解决的 NP 完全问题)。这两种方法是:

  • 递归
  • 动态规划

递归方法更容易理解,但动态规划方法更高效、更优雅。我建议您查看this 站点,并调整解决方案以适应您的问题(而不是求和,将子集添加到您的子数组)。

【讨论】:

    【解决方案2】:

    下面是一种递归方法,可以为给定的整数数组创建所有 k 个子集的集合:

    import java.util.ArrayList;
    
    public class Solution {
        public static void ksubsets(int[] arr, int left, int idx,
                                    ArrayList<Integer> curArr, ArrayList<ArrayList<Integer>> result) {
            if (left <= 0) {
                ArrayList<Integer> tmp = new ArrayList<>(curArr);
                result.add(tmp);
                return;
            }
            for (int i = idx; i < arr.length; i++) {
                curArr.add(arr[i]);
                ksubsets(arr, left - 1, i + 1, curArr, result);
                curArr.remove(curArr.size() - 1);
            }
        }
    
        public static void main(String[] args) {
            int[] arr = {1, 2, 3, 4};
            int left = 3; // specifies the subset size
            int idx = 0;
            ArrayList<Integer> curArr = new ArrayList<>();
            ArrayList<ArrayList<Integer>> result = new ArrayList<>(); // contains all calculated subsets
            Solution.ksubsets(arr, left, idx, curArr, result);
            System.out.println(result.size());
        }
    }
    

    ksubsets(...) 方法执行后,result 包含以下ArrayLists

    1,2,3

    1,2,4

    1,3,4

    2,3,4

    在大小为 4 的集合中存在大小为 3 的所有不同子集。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-16
      • 2015-08-14
      • 1970-01-01
      • 2021-04-11
      • 2015-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多