-1

I have written code to reverse an array that has Time Complexity: O(n).

Is there a faster method?

My code:

 void reverseArray(int arr[], int start, int end){
        int temp;
        if(start >= end)
            return;
        temp = arr[start];
        arr[start] = arr[end];
        arr[end] = temp;
        reverseArray(arr, start+1, end-1);   
    }
4
  • 4
    It might not be faster, but why not just convert it to a List and use Collections.reverse()? I usually trust that the people who wrote Java are smarter than I am, plus it makes the code more readable. Commented Jan 9, 2014 at 14:46
  • 5
    I'm not sure if it will run faster, but why don't you just use a simple while loop with two indexes, one starting from the left and one from the right, instead of a recursive call to your function ? And don't reinvent the wheel, use ArrayUtils.reverse(int[] arr) from apache library. Commented Jan 9, 2014 at 14:47
  • 3
    @user2336315 - Couldn't agree more.. In recursion, the greater the size the higher the probablity of StackOverFlowError. Commented Jan 9, 2014 at 14:48
  • 1

5 Answers 5

14

Literally reversing the elements in memory can't be done any faster than O(n). However, you could make a wrapper class that indexes the array reversed. So, in fact you don't reverse the array, but only access the elements backwards.

The code you have is O(n), but terrible because of the recursion. Make it flat and you will experience some benefit.

public static void reverseArray(int arr[], int start, int end)
{
    int len = end - start;
    if(len <= 0) return;

    int len2 = len >> 1;
    int temp;

    for (int i = 0; i < len2; ++i)
    {
        temp = arr[start + i];
        arr[start + i] = arr[end - i - 1];
        arr[end - i - 1] = temp;
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

I like your suggestion of the wrapper class
4

You are using recursion which is not as fast as a loop. You are still O(n) but with faster time to use a loop. Something like:

static void reverseArray(int arr[]){
   for (int start=0,end=arr.length-1;start<=end;start++,end--) {
      int temp = arr[start];
      arr[start] = arr[end];
      arr[end] = temp;
   }
}

For something like this you will be better off using methods provided in the Java libraries to do it though.

11 Comments

the main problem of the recursion is the memorie which is needed.
It's both slower and uses more memory, and you are limited in iteration depth whereas a loop isn't.
@kai - Tim is right... Recursion is slower because too many operations occur on the stack each time function is called recursively
Be nice to know why I got a downvote :s
@TheLostMind i know, i only want to point out that there is a memory problem too. thats not my downvote :)
|
4

You could use some intermediary function:

int rev(int i) {
    return arr.length - i - 1;
}
//...
arr[rev(i)] = 5; // reverse reference

Comments

2

If you use static arrays, since you will need to access every element once in order to reverse it, there is no smaller complexity than n.

However, if you use a double linked list, then by definiton you have access to the elements in both directions. From head to tail and from tail to head, because there are double pointers in the Node class used. Therefore, reverse is not even needed, but rather you iterate from tail to head when needed.

5 Comments

You don't need to reverse an array either, you can just write a wrapper class that indexes the array in reverse (as per this answer).
@Dukeling Yes, however, the algorithm complexity for this is still O(n). On the other hand, when a double linked list is used, you do not have to make that step. Therefore the complexity for that is just O(1). You just access the elements from tail to head directly.
No, you can assign the array to a member of the wrapper class (or it can start off in the wrapper class) and simply set a "reversed" flag in the wrapper class (indicating to the accessors and mutators that they should indexes the array in reverse), both in O(1).
I mean something like this.
@Dukeling So accessing the array in the other way arround when it is marked as reversed. In the example given, indeed the complexity is O(1). Thank you for the specification.
0

Recursion vs Iteration. Function calls (recursion) cost cycles. Thus, for this solution, I would go with an iterative approach. Other things to note are: even/odd sized arrays, empty arrays, arrays with only 1 item. An untested solution is:

void reverseArray(int arr[]){

  //check input
  if(arr.length <= 1){
    return;
  }

  int arrLength = arr.length;
  int swpIndex;

  for (int i = 0; i < arrLength / 2 - 1; i++){
    swpIndex = arrLength - i - 1;

    swp = arr[i];
    arr[i] = arr[swpIndex]; 
    arr[swpIndex] = swp;
  }
}

This stores a few values so that it really avoids repitition (i.e. extra cycles). It also checks for arrays that don't need reversing.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.