diff --git a/src/main/java/MainExercises.java b/src/main/java/MainExercises.java index 6b8400b..b74b3a7 100644 --- a/src/main/java/MainExercises.java +++ b/src/main/java/MainExercises.java @@ -1,4 +1,5 @@ import java.util.ArrayList; +import java.util.List; public class MainExercises { @@ -150,64 +151,39 @@ public class MainExercises public int[][] intPartitions(int n) { - if(n == 1){ - return new int[][]{{1}}; - } + List> allPartitions = new ArrayList<>(); + ArrayList current = new ArrayList<>(); + generatePartition(n, n, current, allPartitions); - ArrayList result = new ArrayList<>(); - int[] current = new int[n]; // current partition, to be built - - // we use stack arrays to have the situation saved. - int[] remainingStack = new int[n*n]; // remaining value, to be added -// int[] maxValueStack = new int[n*n]; // maximum number we can use, to prevent repeating partitions - int[] nextTryStack = new int[n*n]; // the next number we try - 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; + // converting ArrayList of ArrayLists into a 2d array + int[][] result = new int[allPartitions.size()][]; + for (int i = 0; i < allPartitions.size(); i++) { + List sublist = allPartitions.get(i); + result[i] = new int[sublist.size()]; + for (int j = 0; j < sublist.size(); j++) { + result[i][j] = sublist.get(j); } + } + + return result; - 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; + } + private void generatePartition(int remaining, int maxValue, List currentPartition, List> allPartitions){ + if(remaining == 0){ + allPartitions.add(new ArrayList<>(currentPartition)); + return ; } - int[][] output = new int[result.size()][]; - for(int i = 0; i < result.size(); i++){ - output[i] = result.get(i); - } + 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); - return output; + 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) + */ + } }