I think the design of the API is largely subjective and / or should greatly influence the “use cases” of the API. What your API uses, on the other hand, is completely dependent on client code.
Having said all this, I personally will take advantage of the method overload and move on to the following structure:
Method with all parameters:
void someFunction(int[] input1, int[] input2, int offset, int length, int[] output)
This is the main function. All other functions simply call this the corresponding parameters.
int[] someFunction(int[] input1, int[] input2, int offset, int length)
This calls the first function, but allocates and returns the output array on behalf of the caller.
void someFunction(int[] input1, int[] input2, int[] output)
int[] someFunction(int[] input1, int[] input2)
Note that the general strategy is to make the parameter list shorter by eliminating the “optional” parameters.
In general, I try to avoid changing the behavior of the method depending on whether the parameter (for example, the output array) is null . This can make it difficult to catch such errors. Therefore, I prefer two different calling styles - one where the output parameter is provided (and required), and one where the method returns its output.