Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficiently reverse the order of the words (not characters) in an array of characters

Given an array of characters which forms a sentence of words, give an efficient algorithm to reverse the order of the words (not characters) in it.

Example input and output:

>>> reverse_words("this is a string")
'string a is this'

It should be O(N) time and O(1) space (split() and pushing on / popping off the stack are not allowed).

The puzzle is taken from here.

like image 625
jfs Avatar asked Sep 06 '08 12:09

jfs


People also ask

How do you reverse words in an array?

Once you got the array, you can create an ArrayList from an array, and then you are eligible to use Collections. reverse() method. This will reverse your ArrayList and you will have all the words in reverse order, now all you need to do is concatenate multiple String by iterating over ArrayList.

How do you reverse the order of words in a string?

This can done in many ways. One of the solutions is given in Reverse words in a string . This can be done in more simpler way by using the property of the “%s format specifier” . Property: %s will get all the values until it gets NULL i.e. '\0'.


2 Answers

A solution in C/C++:

void swap(char* str, int i, int j){
    char t = str[i];
    str[i] = str[j];
    str[j] = t;
}

void reverse_string(char* str, int length){
    for(int i=0; i<length/2; i++){
        swap(str, i, length-i-1);
    }
}
void reverse_words(char* str){
    int l = strlen(str);
    //Reverse string
    reverse_string(str,strlen(str));
    int p=0;
    //Find word boundaries and reverse word by word
    for(int i=0; i<l; i++){
        if(str[i] == ' '){
            reverse_string(&str[p], i-p);
            p=i+1;
        }
    }
    //Finally reverse the last word.
    reverse_string(&str[p], l-p);
}

This should be O(n) in time and O(1) in space.

Edit: Cleaned it up a bit.

The first pass over the string is obviously O(n/2) = O(n). The second pass is O(n + combined length of all words / 2) = O(n + n/2) = O(n), which makes this an O(n) algorithm.

like image 67
Thomas Watnedal Avatar answered Sep 20 '22 12:09

Thomas Watnedal


pushing a string onto a stack and then popping it off - is that still O(1)? essentially, that is the same as using split()...

Doesn't O(1) mean in-place? This task gets easy if we can just append strings and stuff, but that uses space...

EDIT: Thomas Watnedal is right. The following algorithm is O(n) in time and O(1) in space:

  1. reverse string in-place (first iteration over string)
  2. reverse each (reversed) word in-place (another two iterations over string)
    1. find first word boundary
    2. reverse inside this word boundary
    3. repeat for next word until finished

I guess we would need to prove that step 2 is really only O(2n)...

like image 26
Daren Thomas Avatar answered Sep 20 '22 12:09

Daren Thomas