Could this algorithm be made better?

早过忘川 提交于 2021-01-29 02:59:08

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!