可以使这种算法更好吗?

时间:2020-03-31 10:32:54

标签: algorithm

我有一个问题,在我写的一种算法中,要分离出左侧的所有偶数和右侧的奇数。

示例:输入:

{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)或更好?

3 个答案:

答案 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


如果元素的顺序重要

  • 您可以在新列表中收集所有奇数。
  • 将所有偶数都移到左侧。
  • 将列表中的所有奇数一一分配给偶数结束的数组。
  • 这会将空间复杂度提高到O(n)。