java - 如何以所有可能的组合将整数数组分成 N 个部分?

标签 java arrays

我试图将一个数组分成 N 个部分,条件是所有部分至少有 1 个数字。

示例:如果数组 [5, 10, 10, 30] 被分成 2 (N=2) 个部分,那么所有可能的部分组合将是:

  • 组合 #1:5 | 10、10、30
  • 组合 #2:5、10 | 10、30
  • 组合 #3:5、10、10 | 30

到目前为止我的代码

public static void main(String[] args) {

        int[] a = { 5, 10, 10, 30 };
        int maxElement = 3;
        int count = 1;
        while (count <= maxElement) {
            printCombinations(count, a);
            count++;
        }

    }

    public static void printCombinations(int count, int[] a) {
        System.out.println("start printing");
        for (int index = 0; index < count; index++) {

            System.out.println(a[index]);
        }
        System.out.println("----");
        for (int index = count; index < a.length; index++) {

            System.out.println(a[index]);
        }
        System.out.println("end printing");
    }

它正在按预期打印组合。但我无法弄清楚如何将其概括为 N。感谢任何帮助。

最佳答案

我必须将数组转换为 ArrayList,以便更轻松地处理数据集。

我使用递归来分离数组的左侧部分并递归计算右侧部分。

可能不是最好的代码,但它确实有效。如果有时间,我会尝试改进变量名称。

解释 List<List<List<Integer>>> 的使用:-

假设输入是

a = { 5, 10, 10, 30 }
n = 2

组合将是:-

combination #1: 5 | 10, 10, 30
combination #2: 5, 10 | 10, 30
combination #3: 5, 10, 10 | 30

为了存储这3个组合,最外层的List<>被使用。

第二个List<>在每个组合中存储部分。因此组合 #1 将有 2 个部分,[5] 和 [10, 10, 30]。

最里面List<Integer>用于存储每个部分中的整数。因此,第 #2 部分与 #1 的组合将包含 10、10、30 的列表。

解决方案

public static void main(String[] args) {
    Integer[] a = {5, 10, 10, 30};
    final List<List<List<Integer>>> combinations = getCombinations(2, Arrays.asList(a));
    for (List<List<Integer>> combination : combinations)
        System.out.println(combination);
}

public static List<List<List<Integer>>> getCombinations(int n, List<Integer> a) {
    if (n == 1) {
        List<List<List<Integer>>> singleLine = new ArrayList<>();
        List<List<Integer>> singleSection = new ArrayList<>();
        singleSection.add(a);
        singleLine.add(singleSection);
        return singleLine;
    }
    List<List<List<Integer>>> res = new ArrayList<>();
    if (n > a.size()) return res;
    if (n == a.size()) {
        List<List<Integer>> sections = new ArrayList<>();
        for (Integer e : a) {
            List<Integer> l = new ArrayList<>();
            l.add(e);
            sections.add(l);
        }
        List<List<List<Integer>>> lines = new ArrayList<>();
        lines.add(sections);
        return lines;
    }
    for (int i = 1; i <= a.size() - n + 1; i++) {
        List<List<Integer>> left = new ArrayList<>();
        List<Integer> leftElements = new ArrayList<>();
        left.add(leftElements);
        leftElements.addAll(a.subList(0, i));
        List<List<List<Integer>>> subResult = getCombinations(n - 1, a.subList(i, a.size()));
        for (List<List<Integer>> r : subResult) {
            res.add(Stream.concat(left.stream(), r.stream())
                    .collect(Collectors.toList()));
        }
    }
    return res;
}

输入 1

a = {5, 10, 10, 30}
n = 2

输出 1

[[5], [10, 10, 30]]
[[5, 10], [10, 30]]
[[5, 10, 10], [30]]

输入 2

a = {5, 10, 10, 30}
n = 3

输出 2

[[5], [10], [10, 30]]
[[5], [10, 10], [30]]
[[5, 10], [10], [30]]

输入 3

a = {5, 10, 10, 30, 40}
n = 3

输出 3

[[5], [10], [10, 30, 40]]
[[5], [10, 10], [30, 40]]
[[5], [10, 10, 30], [40]]
[[5, 10], [10], [30, 40]]
[[5, 10], [10, 30], [40]]
[[5, 10, 10], [30], [40]]

关于java - 如何以所有可能的组合将整数数组分成 N 个部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52247905/

相关文章:

java - Android VpnService 转发数据包

Java像图一样遍历一个大的HashMap

java - 如何根据需要定义具有不同自定义类型键和值序列化器的 kafka 生产者?

c++ - 如何在跳棋游戏中移动棋子

Javascript 按降序键对数组进行排序 Google Chrome

c - 从 int** 读取 const 值,该值是从 int[][] 初始化的

java - 如何使用 java 运行可执行文件 portace 从位图文件生成 svg 文件

java - JOOQ - 使用 RecordMapper 映射单个记录

javascript - 使用 javascript 获取复选框属性(数组)

arrays - 嵌套 *ngFors - 更好的选择? ( Angular 7)