Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
440 views
in Technique[技术] by (71.8m points)

java - Building permutation that sums to a number efficiently

I am looking to generate more permutation that sums up to a given number N, however this time more efficiently. Since by general methods, it takes forever to create 100+ permutations.

However I'm at another impasses where I find it extremely difficult to build upward permutations that utilized the permutations that are already solved n-1 to generate every permutation that sums to n.

I would greatly appreciate any help! I still a total newbie, so sorry if it seems like an easy question. but this is bending my mind!

Input(n): 4

Output: [[4],[3,1],[1,3],[2,2],[1,1,2],[1,2,1],[2,1,1],[1,1,1,1]]
import java.util.*;
import javax.naming.PartialResultException;

public class Perm {
    private List<List<Integer>> computePerm(int n) {
        // I totally lost it here
        if (n == 0) {
            return computePerm(0);
        } else {
            List<Integer> arr2 = new ArrayList<>();
            for (List<Integer> entry : arr1) {
                for (int i = 0; i < entry.size(); i++) {
                    arr2.add(entry.get(i)); // This obviously doesn't work
                }
            }
        }
        return computePerm(n);
    }

    public static void main(String[] args) {
        Perm perm1 = new Perm();
        System.out.println(computePerm(4));
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This can be done recursively. The stack contains what you've previously built and adds onto it.

While I'd worry about correctness first, then optimization, I don't see a way to get around the fact that you'll need to enumerate each of the integer partitions, so the complexity is going to be exponential unless I'm missing something.

import java.util.ArrayDeque;
import java.util.ArrayList;

class Main {
    public static ArrayList<ArrayList<Integer>> partition(int n) {
        var result = new ArrayList<ArrayList<Integer>>();
        partition(n, new ArrayDeque<>(), result);
        return result;
    }

    private static void partition(int n, ArrayDeque<Integer> path, 
                                  ArrayList<ArrayList<Integer>> result) {
        if (n == 0) result.add(new ArrayList<Integer>(path));

        for (int i = 1; i <= n; i++) {
            path.offer(i);
            partition(n - i, path, result);
            path.pop();
        }
    }

    public static void main(String[] args) {
        for (var result : partition(4)) {
            for (int i : result) {
                System.out.print(i + " ");
            }

            System.out.println();
        }
    }
}

Output:

1 1 1 1 
1 1 2 
2 2 1 
1 3 
2 1 1 
1 2 
3 1 
4 

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...