How would I separate even and odd integers in an array with order preserved ?
Modifications must be in place and the return is a void
, and can only use built in methods.
An example would be:
{4, 5, 8, 16, 45, 12, 67, 13} -> {4, 8, 16, 12, 5, 45, 67, 13}
You can easily solve this with one iteration, remembering the index of the current border and swapping elements.
So for your example, the process will be:
{ 4, 5, 8, 16, 45, 12, 67, 13 } // swap 4 with 4
^
{ 4, 5, 8, 16, 45, 12, 67, 13 }
^
{ 4, 8, 5, 16, 45, 12, 67, 13 } // swap 5 with 8
^
{ 4, 8, 16, 5, 45, 12, 67, 13 } // swap 5 with 16
^
{ 4, 8, 16, 12, 45, 5, 67, 13 } // swap 5 with 12
^
Where the ^
shows the current border index, which is always one ahead of the even values, pointing at the index where you want to swap the next even value to.
Here is the code for that:
int borderIndex = 0;
for (int i = 0; i < values.length; i++) {
int value = values[i];
if (value % 2 == 0) {
// swap
values[i] = values[borderIndex];
values[borderIndex] = value;
borderIndex++;
}
}
Now, this solution already preserves the order of the even numbers out of the box. But if you pay close attention you see that it does not preserve order of the odd values. It goes wrong as soon as you have multiple odd values after each other before an even value, like
..., 5, 45, 12, ...
because it will then swap 5
with 12
resulting in 12, 45, 5
instead of 12, 5, 45
.
Even worse when there are multiple odd values:
..., 5, 7, 9, 11, 12, ...
resulting in 12, 7, 9, 11, 5
.
In order to fix this, we have to not just swap 5
with the even value 12
but actually swap all the way back to 5
. So:
swap 12 with 11
swap 12 with 9
swap 12 with 7
swap 12 with 5
basically shifting down 12
from right to left, until it stands right in front of 5
.
We can do so easily with a simple loop that moves from 12
(at i
) to 5
(at borderIndex
):
int borderIndex = 0;
for (int i = 0; i < values.length; i++) {
int value = values[i];
if (value % 2 == 0) {
// swap from i to borderIndex
for (int j = i; j > borderIndex; j--) {
values[j] = values[j - 1];
values[j - 1] = value;
}
borderIndex++;
}
}
You can also do it like this. In this case your sorting them on their inherent nature as opposed to their relationship to each other.
Integer [] arr = {4, 5, 8, 16, 45, 12, 67, 13};
Arrays.sort(arr, Comparator.comparing(a->a % 2));
System.out.println(Arrays.toString(arr));
prints
[4, 8, 16, 12, 5, 45, 67, 13]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.