Change algorithm of intPartitions method (recursive solution)
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class MainExercises
|
public class MainExercises
|
||||||
{
|
{
|
||||||
@@ -150,64 +151,39 @@ public class MainExercises
|
|||||||
|
|
||||||
public int[][] intPartitions(int n) {
|
public int[][] intPartitions(int n) {
|
||||||
|
|
||||||
if(n == 1){
|
List<List<Integer>> allPartitions = new ArrayList<>();
|
||||||
return new int[][]{{1}};
|
ArrayList<Integer> current = new ArrayList<>();
|
||||||
}
|
generatePartition(n, n, current, allPartitions);
|
||||||
|
|
||||||
ArrayList<int[]> result = new ArrayList<>();
|
// converting ArrayList of ArrayLists into a 2d array
|
||||||
int[] current = new int[n]; // current partition, to be built
|
int[][] result = new int[allPartitions.size()][];
|
||||||
|
for (int i = 0; i < allPartitions.size(); i++) {
|
||||||
// we use stack arrays to have the situation saved.
|
List<Integer> sublist = allPartitions.get(i);
|
||||||
int[] remainingStack = new int[n*n]; // remaining value, to be added
|
result[i] = new int[sublist.size()];
|
||||||
// int[] maxValueStack = new int[n*n]; // maximum number we can use, to prevent repeating partitions
|
for (int j = 0; j < sublist.size(); j++) {
|
||||||
int[] nextTryStack = new int[n*n]; // the next number we try
|
result[i][j] = sublist.get(j);
|
||||||
int[] lenStack = new int[n*n]; // length of current partition, gives us the next index in current
|
|
||||||
int head = 0; // works like a pointer, it makes stack arrays make sense.
|
|
||||||
|
|
||||||
remainingStack[0] = n;
|
|
||||||
// maxValueStack[0] = n;
|
|
||||||
nextTryStack[0] = n;
|
|
||||||
lenStack[0] = 0;
|
|
||||||
|
|
||||||
while(head >= 0){
|
|
||||||
int remaining = remainingStack[head];
|
|
||||||
// int maxValue = maxValueStack[head];
|
|
||||||
int nextTry = nextTryStack[head];
|
|
||||||
int partitionLen = lenStack[head];
|
|
||||||
|
|
||||||
if(remaining == 0){ // partition has been completed
|
|
||||||
//
|
|
||||||
int[] partition = new int[partitionLen];
|
|
||||||
System.arraycopy(current, 0, partition, 0, partitionLen);
|
|
||||||
result.add(partition);
|
|
||||||
head--;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nextTry <= 0){ // no choices left
|
|
||||||
head--;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int chosen = nextTry;
|
|
||||||
nextTryStack[head] = chosen - 1; // next value to be tried
|
|
||||||
current[partitionLen] = chosen; // adding selected number
|
|
||||||
|
|
||||||
// generating next number for the partition
|
|
||||||
head++;
|
|
||||||
remainingStack[head] = remaining - chosen;
|
|
||||||
// maxValueStack[head] = chosen;
|
|
||||||
nextTryStack[head] = Math.min(chosen, remaining - chosen);
|
|
||||||
lenStack[head] = partitionLen + 1;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int[][] output = new int[result.size()][];
|
return result;
|
||||||
for(int i = 0; i < result.size(); i++){
|
|
||||||
output[i] = result.get(i);
|
}
|
||||||
|
|
||||||
|
private void generatePartition(int remaining, int maxValue, List<Integer> currentPartition, List<List<Integer>> allPartitions){
|
||||||
|
if(remaining == 0){
|
||||||
|
allPartitions.add(new ArrayList<>(currentPartition));
|
||||||
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
for (int i = Math.min(maxValue, remaining); i >= 1; i--){ // preventing choosing the bigger number between maxValue and remaining, this way repeating partitions
|
||||||
|
currentPartition.add(i);
|
||||||
|
generatePartition(remaining - i, i, currentPartition, allPartitions);
|
||||||
|
|
||||||
|
currentPartition.removeLast(); /*
|
||||||
|
after the recursive call returns. we need to undo adding i.
|
||||||
|
this way we can try adding i again. ( remaining may not be 0 yet)
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user