I am writing a function that takes an array and an integer number and returns an array of all the partitions into subarrays (so an array of arrays of subarrays). The number of subarrays is exact the integer number passed to the function. And the subarrays have to be continuous, meaning the original order of items in the array has to be preserved. Also no subarray can be empty. They have to have at least one item in it. For example:
const array = [2,3,5,4]
const numOfSubarray = 3
const subarrays = getSubarrays(array, numOfSubarray)
// [[[2, 3], [5], [4]], [[2], [3, 5], [4]], [[2], [3], [5, 4]]]
Here is my attempt:
function getSubarrays(array, numOfSubarray) {
const results = []
const recurse = (index, subArrays) => {
if (index === array.length && subArrays.length === numOfSubarray) {
results.push([...subArrays])
return
}
if (index === array.length) return
// 1. push current item to the current subarray
// when the remaining items are more than the remaining sub arrays needed
if (array.length - index - 1 >= numOfSubarray - subArrays.length) {
recurse(
index + 1,
subArrays.slice(0, -1).concat([subArrays.at(-1).concat(array[index])])
)
}
// 2. start a new subarray when the current subarray is not empty
if (subArrays.at(-1).length !== 0)
recurse(index + 1, subArrays.concat([[array[index]]]))
}
recurse(0, [[]], 0)
return results
}
Right now it seems to be working. But I wanted to know what is the time/space complexity of this algorithm. I think it is definitely slower than O(2^n)
. Is there any way to improve it? Or any other solutions we can use to improve the algorithm here?