Я ищу решение следующей проблемы:
Даны два целых числа n и k, вернуть все возможные комбинации k чисел из 1 2 3 ... n.
Убедитесь, что комбинации отсортированы.
Чтобы уточнить,
- Внутри каждой записи элементы должны быть отсортированы. [1, 4] — допустимая запись, а [4, 1] — нет.
- Записи должны быть отсортированы внутри себя.
Пример: если n = 4 и k = 2, решение:
[
[1,2],
[1,3],
[1,4],
[2,3],
[2,4],
[ 3,4],
]
Это решение, которое я придумал:
public ArrayList<ArrayList<Integer>> combine(int n, int k) {
//variable where the resultant sets of of numbers are to be stored
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
//finding all the subsets from 1-n of size k and storing them in result
subset(n,result,k);
//sorting the resultant set of subsets lexicographically
Collections.sort(result,new Comparator<ArrayList<Integer>>(){
@Override
public int compare(ArrayList<Integer> a,ArrayList<Integer> b){
int aSize = a.size();
int bSize = b.size();
for(int i=0;i<(int)Math.min(aSize,bSize);i++){
int comparison = Integer.compare(a.get(i),b.get(i));
if(comparison!=0) return comparison;
}
return Integer.compare(aSize,bSize);
}
});
return result;
}
void subset(int n,ArrayList<ArrayList<Integer>> result,int size){
for(int i=0;i<(1<<n);++i){
//the arraylist to be added to the result
ArrayList<Integer> element = new ArrayList<Integer>();
//iterating 2^n times since those are the total number of possible subsets
for(int j=0;j<n;++j)
if((i&(1<<j))>0)
element.add(j+1);
//only adding the resultant subset to the result if it matches the size criteria
if(element.size() == size)
result.add(element);
}
}
Я смотрю на этот ответ и не могу не думать, что должен быть более оптимальный способ сделать это.
Судя по всему, эта программа имеет временную сложность O(nlogn * 2^n). Что совсем плохо. Я пытаюсь рассчитать каждое подмножество, прежде чем проверять, соответствуют ли они критериям размера. Любой способ найти количество подмножеств, повторяя только nCk раз?
nCk — количество комбинаций, которые мы можем надеяться найти. Где nCk = n!/(k!*(n-k)!)