Edit - I deleted all the unnecessary contextual explanation - too verbose and ultimately unrelated to the problem. As a result, I split the coordinate arrays in the process of constructing a balanced KD tree ( see the Wikipedia article, โBuildingโ section for more. K parallel arrays of n elements, each of which must be divided into the same comparison)
This is not homework. I wrote the question so that it conveys all the nuances.
Given the sorted arrays:
int[] ints = { 0, 1, 2, 3, 4, 5, 6 }; //this one is important - my current solution fails on this int[] ints2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Note. Due to the explanation given by the colleague, all that is guaranteed for these arrays is that element[n]
will be less than or equal to element[n+1]
.
Successful operations on them will divide them into two auxiliary arrays L
and R
(indicated below):
/*ints == */ { 1, 3, 5, 0, 2, 4, 6 } /*|> L <| |> R <|*/ /*ints2 == */ { 1, 3, 5, 7, 9, 0, 2, 4, 6, 8 } /*|> L <| |> R <|*/
L
contains integers that are odd, and R
contains those that are even, while preserving the original sort order of these elements inside these subarrays.
Ideally, the function DOES NOT resort to re-sorting the elements (a lengthy sorting operation is already performed in advance), and it will not use a temporary array. I believe this means that I am looking for O (N) complexity and O (1) memory.
The function can be equipped with the initial and final elements of each auxiliary array - that is, the caller can know in advance how many objects will fall on the left / right side (perhaps by scanning the array in advance for the odd / even), Change , in fact, it starts as an array; therefore, a solution that can work without these values โโis good, because otherwise a complete solution can only be, at best, O (2n) complexity in reality, if an initial pass is required.
This is where my current attempt is now - I updated it and commented on it from what was in the original post.
public void DivideSubArray(int[] array, int leftStart, int leftCount, int rightStart, int rightCount) { int currentLeft = leftStart, currentRight = rightStart; int leftCounter = leftCount; int temp; int readahead; while (leftCounter != 0) { if ((array[currentLeft] % 2) == 0) {
Called as follows:
int numOdd = ints.Count(i => (i % 2) == 1); DivideSubArray(ints, 0, numOdd, numOdd, ints.Length - numOdd);
It produces the expected array for ints
(and many other arrays), but not ints2
:
{ 1, 5, 3, 7, 9, 0, 2, 6, 4, 8 }
So, it breaks correctly - but the swaps are 3,5
and 6,4
. I understand why : because in the first cycle, 5
changes to the left, then 2
spreads, because the algorithm says that 5
is odd and should remain. I have a decision tree written that will fix it, but several cycles have followed that indicate that the solution is recursive.
I'm struggling to figure out how to get around this without having to do more sorting operations inside the auxiliary array or creating temporary lists / arrays as a workspace. Of course, however, sorting can increase complexity, but save the need for memory; and if that turns out to be the quickest solution, then it would be wise to use it.
In my answer you can see my fastest (at runtime) and best memory option. As a criterion - the above attempt not only leads to an incorrect result, but also takes 3 times as much code in my answer.
I believe that there should be an easy way to use one "spare" variable to replace elements - I just do not see it - I hope the collective brain of SO will be :)
Of course, if the answer is no, so be it.