问题
I have a question, in one of the algorithms, I had written, to seperate out, all the even numbers to the left and odd numbers to the right.
Example: Input:
{ 12, 10, 52, 57, 14, 91, 34, 100, 245, 78, 91, 32, 354, 80, 13, 67, 65 }
Output:
{12,10,52,80,14,354,34,100,32,78,91,245,91,57,13,67,65}
Below is the algorithm
public int[] sortEvenAndOdd(int[] combinedArray) {
int endPointer = combinedArray.length - 1;
int startPointer = 0;
for (int i = endPointer; i >= startPointer; i--) {
if (combinedArray[i] % 2 == 0) {
if (combinedArray[startPointer] % 2 != 0) {
int temp = combinedArray[i];
combinedArray[i] = combinedArray[startPointer];
combinedArray[startPointer] = temp;
startPointer = startPointer + 1;
} else {
while (combinedArray[startPointer] % 2 == 0 &&
(startPointer != i)) {
startPointer = startPointer + 1;
}
int temp = combinedArray[i];
combinedArray[i] = combinedArray[startPointer];
combinedArray[startPointer] = temp;
startPointer = startPointer + 1;
}
}
}
return combinedArray;
}
Anybody, have any suggestions, for it make it to O(n) or better ?
回答1:
Your code is O(n), but it's a bit more complicated than it needs to be. Here's an improvement.
startPointer = 0;
endPointer = a.length - 1;
while (startPointer < endPointer)
{
if (a[startPointer] % 2 != 0)
{
// move endPointer backwards to even number
while (endPointer > startPointer && a[endPointer] % 2 != 0)
{
--endPointer;
}
swap(a[startPointer], a[endPointer]);
}
++startPointer;
}
By the way, the operation is more of a partition than a sort. I think a better function name would be partitionEvenOdd.
回答2:
Make two queue one for even and another for odd . When any new number come push into respective queue and when all number finished then traverse first even queue and push into answer vector and then odd queue number . This is O(n) solution .I hope I am able to explain the solution .
Sorry for english.
If you want then I can post implementation but you should try.
回答3:
You can't do it better than O(n) time, but you can make your code more concise.
Looking at your solution, since order of elements doesn't matter, you can simply keep a pointer variable which goes from last to first and keep swapping elements with this pointer.
Snippet:
private static void solve(int[] arr){
for(int i=arr.length-1,ptr = i;i>=0;--i){
if((arr[i] & 1) == 1){
swap(arr,i,ptr--);
}
}
}
private static void swap(int[] arr,int x,int y){
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
Demo: https://onlinegdb.com/HyKNVMbwL
If the order of the elements matter
- You can collect all odd ones in a new list.
- Move all even ones to the left.
- Assign all odd ones one by one from the list to the array from where even ones ended.
- This will increase space complexity to O(n).
来源:https://stackoverflow.com/questions/60948523/could-this-algorithm-be-made-better