我有一个问题,在我写的一种算法中,要分离出左侧的所有偶数和右侧的奇数。
示例:输入:
{12,10,52,57,14,91,34,100,245,78,91,32,354,80,13,67,65}
输出:
{12,10,52,80,14,354,34,100,32,78,91,245,91,57,13,67,65}
下面是算法
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;
}
有人有什么建议,因为它可以达到O(n)或更好?
答案 0 :(得分:2)
您的代码为O(n),但比所需的要复杂一些。这是一个改进。
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;
}
顺便说一句,操作更多的是分区而不是排序。我认为更好的函数名称为partitionEvenOdd
。
答案 1 :(得分:0)
使两个队列一个偶数,另一个偶数。当有任何新的号码进入各自的队列,当所有号码完成后,先遍历偶数队列并推入应答向量,然后进入奇数队列。这是O(n)解决方案。希望我能解释该解决方案。
对不起,英语。
如果您愿意,我可以发布实现,但您应该尝试。
答案 2 :(得分:0)
您做不到比O(n)更好的时间,但是您可以使代码更简洁。
查看您的解决方案,由于元素的顺序无关紧要,因此您可以简单地保留一个指针变量,该变量从倒数第一到第一,并保持与此指针交换元素。
代码段:
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;
}
演示:https://onlinegdb.com/HyKNVMbwL
如果元素的顺序重要