【问题标题】:Java program for permutation and combination用于排列组合的Java程序
【发布时间】:2018-05-22 20:41:50
【问题描述】:

我得到了一个具有以下输入的程序

List of integers = {1,2,3}
int n = 5;

输出应该是列表元素的唯一组合,可以添加形成整数n。

预期输出 = 5 因为使用上述数组可以形成 5 的唯一组合是

1,1,1,1,1
1,1,1,2
1,1,3
2,2,1
2,3

我创建的函数如下所示

static void printAllCobinations(List<Integer> rooms,int t){
    int count = 0;
    for (int i=0;i<rooms.size();i++){
        int temp = t;
        while (temp>0){
            if((rooms.contains(temp))){
                count++;
            }
            temp-=rooms.get(i);
        }
    }

它给出的输出为 6,除了上述场景之外,它还考虑 3,2 也。

实际期望是如果2, 3被认为不需要考虑3,2。

我怎样才能做到这一点?

注意:输入数组和 n 可以改变。

【问题讨论】:

  • 如果你打印出来,你的函数的当前输出是 321312,结果是 6。我认为你需要完全重新考虑你的函数
  • 虽然这个问题可以通过重复排列的帮助来解决,将每个结果的项目总和与目标结果进行比较,但这种方法只有在n非常小时是好的,因为这个算法的复杂度,如果我没记错的话,就是 O(n!)。所以对于 n=5,n 的值!是 120,n=12 大约需要 479001600 次迭代。所以即使pc很强大,等待结果的时间也太长了。

标签: java


【解决方案1】:
int[] arr = new int[s.length() / 2 + 1];

如果 s.length 为 3,则 arr.length = 3

如果 s.length 为 4,则 arr.length = 3

我感觉你的问题就在那里。

作为建议,我建议将转换输入的代码部分与实际计算内容的代码分开。然后分别对其进行测试,看看是否能得到你想要的结果。

【讨论】:

  • 抱歉,该程序将采用一个带有空格分隔数字的字符串,该部分用于将其转换为列表。用正确的代码更新问题
【解决方案2】:

您的任务看起来像硬币交换问题,描述为here。 但不是简单地获取您想要枚举结果的可能排列的数量,因此需要更改代码。

例如,我的解决方案在 Java 8 中可能如下所示:

import java.util.*;
import java.util.stream.Collectors;

public class Solution {
    private List<Integer> rooms;
    private int numberToCheck;
    private Map<Integer, Set<List<Integer>>> cache;

    public Solution(List<Integer> rooms, int numberToCheck) {
        this.numberToCheck = numberToCheck;
        this.cache = new HashMap<>();
        this.rooms = rooms;
    }

    public Set<List<Integer>> solve() {
        return count(numberToCheck);
    }

    private Set<List<Integer>> count(int currentNumber) {
        if (currentNumber <= 0) {
            return Collections.emptySet();
        }

        if (cache.containsKey(currentNumber)) {
            return cache.get(currentNumber);
        }

        Set<List<Integer>> currentSolutions = new HashSet<>();
        cache.put(currentNumber, currentSolutions);
        for (Integer room : rooms) {
            if (currentNumber == room) {
                currentSolutions.add(Collections.singletonList(room));
            }

            Set<List<Integer>> previousSolutions = count(currentNumber - room);
            for (List<Integer> previousSolution : previousSolutions) {
                List<Integer> solution = new ArrayList<Integer>() {{
                    addAll(previousSolution);
                    add(room);
                }};
                Collections.sort(solution);
                currentSolutions.add(solution);
            }
        }
        return currentSolutions;
    }

    public static void main(String[] args) {
        List<Integer> rooms = new ArrayList<Integer>() {{
            add(1);
            add(2);
            add(3);
        }};

        int n = 5;

        Solution solution = new Solution(rooms, n);
        Set<List<Integer>> results = solution.solve();
        System.out.println("Total results: " + results.size());

        System.out.println("Simple results: " + results);
        List<List<Integer>> sortedResults = new ArrayList<List<Integer>>() {{
            addAll(results);
        }};

        sortedResults.sort((list1, list2) -> -Integer.compare(list1.size(), list2.size()));
        System.out.println("Sorted results: " + sortedResults);

        System.out.println("Line by line:");
        sortedResults.forEach(list -> {
            List<String> stringList = list.stream().map(Object::toString).collect(Collectors.toList());
            System.out.println(String.join(",", stringList));
        });
    }
}

输出会是这样的:

Total results: 5
Simple results: [[1, 2, 2], [1, 1, 3], [2, 3], [1, 1, 1, 1, 1], [1, 1, 1, 2]]
Sorted results: [[1, 1, 1, 1, 1], [1, 1, 1, 2], [1, 2, 2], [1, 1, 3], [2, 3]]
Line by line:
1,1,1,1,1
1,1,1,2
1,2,2
1,1,3
2,3

这种方法使用动态编程技术(或记忆化)来存储中间结果以避免不必要的重新计算。方法count对唯一编号只计算一次,房间也只枚举一次。因此,假设房间数量为 k,计算被称为 nk 次。如果我们只需要计算可能的结果,算法复杂度将是 O(kn)。因此,要计算给定任务的结果计数,需要 3*5=15 次迭代。这是非常快的。

但需要枚举所有可能的解决方案,其数量可能会组合(根据输入)增加复杂性,消耗时间和空间,并且有一些排序操作会增加额外的开销,这可能需要嗯!最坏情况下的操作。

这种方法在我的 PC 上运行得非常快,n=200 具有相同的房间列表 {1,2,3},并且需要几秒钟才能显示结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-07
    • 2021-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多