14

Constraints :

  1. O(1) space
  2. O(n) Time

It is not a homework question just a interesting question I came across.

Here are some solutions I could think of but nothing that does it in given constraints.

Method 1

*With O(n) memory *

  • Divide the array in two parts recursively. ( keep dividing till the size <=2 for each sub problem )
  • Sort each sub problem with array first and numbers at end.
  • Merge the sub problem arrays

Method 2

In O(n log n) time

  • Sort the array based Lexicographical order it becomes 1234abcd
  • Reverse both halves of array 4321dcba
  • Reverse the whole string abcd1234

Method 3

If range of numbers was defined

Also if the case was that numbers are in a specific range then I can initialize a int say track= 0; And set the appropriate bit when I come across a number in array eg (1 << a[2] ) . 1. Swap alphabets to first half of array 2. Mark numbers in track variable 3. later use track to fill in second half of array.

Method 4 We can use Method 3 with HashMap if we want to remove the constraint of range of integers but then it will need more memory.

Cannot think of a better way to solve the generic problem in O(1) time and O(n) space.

Generic Problem here refers to:

Given a sequence x1y1x2y2x3y3....xnyn where x1 , x2 are alphabets x1 < x2 <.... < xn and y1y2...yn are integers . y1 < y2 <.... < yn Arrange the output as x1x2...xny1y2...yn

Any suggestions ?

amit modi
  • 1,098
  • 1
  • 11
  • 26
  • You need to figure out how to rearrange 6 characters with no more than 8 actions. (But the "actions" can each be multiple swaps, if need be, and still maintain order N.) (And note that the problem, as you stated it, says nothing about sorting, just rearranging 8 characters into a defined sequence.) – Hot Licks Oct 02 '12 at 02:29
  • @Hot Licks: I tried actually thinking on these lines but ended up with a solution that was not generic. 1.Swap center elements of first half eg ."1b" so we get ab12c3d4. 2. Swap center elements of second half ab12cd34. 3. Swap center 2 element of complete array abcd1234. BUT this technique only works if the size of array is in multiple of 8. – amit modi Oct 02 '12 at 02:34
  • 2
    Define "generic" -- you've not stated a generic problem. You've given an example but no hint as to how that generalizes. – Hot Licks Oct 02 '12 at 02:37
  • Are there restrictions for the input, like some kind of order or just random numbers/characters? – Luiggi Mendoza Oct 02 '12 at 02:39
  • @HotLicks: By generic I meant given a sequence x1y1x2y2x3y3....xnyn where x1 , x2 are alphabets and y1y2...yn are integers . Arrange the output as x1x2...xny1y2...yn – amit modi Oct 02 '12 at 02:40
  • Are x1, x2, x3 sorted like x1 < x2 < x3 or they're just random characters (same for y1, y2... yn)? – Luiggi Mendoza Oct 02 '12 at 02:43
  • @LuiggiMendoza: Yes they are sorted.... – amit modi Oct 02 '12 at 02:46
  • But if they're always interleaved --xyxyxy-- and in order (except for the interleaving) that's different from needing to "sort". – Hot Licks Oct 02 '12 at 02:52
  • (-1 for not being able to clearly state the problem) – Hot Licks Oct 02 '12 at 02:53
  • @HotLicks: Input String is x1y1x2y2x3y3...xnyn where x1 .. x2 .... xn is sorted but alphabets.... and y1.y2....yn is sorted but integers.. You have to generate Output string where O/p = x1x2x3...xnY1y2...yn – amit modi Oct 02 '12 at 02:56
  • 3
    http://www.careercup.com/question?id=14755757 – Smalti Oct 03 '12 at 14:46
  • The question is equivalent to "transpose a 2xN matrix in place". In general, I don't believe there's any O(NM) time, O(1) space way to transpose an MxN matrix in place, so if the 2xN case can be solved efficiently it'll be very interesting! http://en.wikipedia.org/wiki/In-place_matrix_transposition for some references. – Paul Hankin May 10 '14 at 04:46

4 Answers4

6

What is n? Assuming that n is the size of the input:

This is called the convolution of a list. In essence, you have to convert a list of pairs (a,1),(b,2),(c,3),(d,4) to a pair of lists (a,b,c,d),(1,2,3,4). It's the same operation as the transpose of a matrix.

Anyway, you have to think of the structure as a k-dimensional array, where k = lg n. The convolution of the array is what you get when you "move" the value at an index i to index i bitwise rotated. In this case, we want to rotate the indices rightward 1 bit. This means that the convolution is a permutation with a maximum cycle length of k. The trick is then selecting one index from each cycle – this will always include 0 and n-1.

EDIT: Actually, what you probably want is to decompose the permutation into a product of transpositions. Then, all you need to do is swaps.

Thom Smith
  • 13,916
  • 6
  • 45
  • 91
  • Can you please explain this with example "The convolution of the array is what you get when you "move" the value at an index i to index i bitwise rotated." Sorry I did not get it – amit modi Oct 02 '12 at 03:06
  • When n=8, k=3, that means that the permutation is (0)(1 4 2)(3 5 6)(7). 001 => 100 => 010 => 001, and so forth. You convert each index to a k-bit natural number and do a bitwise rotation. Interesting fact: if you perform the convolution k times, you get your original array back. – Thom Smith Oct 02 '12 at 03:14
  • Smit: Thanks now I got it... awesum algo dude :) – amit modi Oct 03 '12 at 04:18
  • @ThomSmith wtf? how does that work? i get what you're saying. but why? – andrew cooke Jun 20 '13 at 00:19
  • Why to which part? I seem to recall had this all worked out on paper last October, but I can try to explain it differently. – Thom Smith Jun 20 '13 at 12:47
  • This is the start of a helpful answer, but the specifics are missing. I don't believe there's a known O(N) time O(1) space way to transpose an arbitrary matrix in situ, so the solution would have to take advantage of the fact we've got a 2 by N matrix. – Paul Hankin May 10 '14 at 04:42
0

Solution:

  1. First (index 0) and last (index n-1) do not move.
  2. Total number of moves is (n - 2)
  3. Even number elements in the source are alphabets. They move into the first half.

    target = j/2 // n is even

  4. Odd number elements in the source are numbers, and they move into the second half.

    target = n/2 + floor(j/2)

  5. Starting from 1th element, move that to its target location.

  6. Move what you find in the target location to its destination and so on until a loop is formed. Note 1: Sometimes, the loop does not include all the elements in the list, so, continue with j + 2 Note 2: Sometimes, at the end of one loop, the desired solution will be achieved, but if we continue, the array will get scrambled again. To fix this, count the number of movements that happened, and cut when it reached n - 2.

You can try running the code, clone and edit here Online Java Compiler IDE


int maxShifts = n - 2; // This is required to fix going around and messing up.
int shifts = 0;

for (int i = 1; i < n && shifts < maxShifts; i+=2) {
  int source = i;
  char itemToMove = array[source];
  do {
    int target;
    if (source % 2 == 0) {
      target = source / 2; // Even index is an alphabet
    } else {
      target = n/2 + source/2; // Odd index is a digit, that goes in the second half
    }
    char tmp = array[target];
    array[target] = itemToMove;
    itemToMove = tmp;

    shifts++;
    source = target;

  } while (i != source /*&& shifts < maxShifts*/); // Full cycle reached

}
JackDaniels
  • 985
  • 9
  • 26
0

The cycle leader algorithm mentioned by @coder works. Just make sure to split the array into sizes of (3^n + 1). Apply cycle leader algorithm and then merge these.

-3

Here is my algorithm in O(n).

void cycle_leader(int *arr, int n) {

for (int i = 1; i < n / 2; i+= 2)
{
    int j = i;
    int save;
    int tmp = arr[i];

    do{
        if (j & 1) //odd index element
            j = n / 2 + j / 2;
        else
            j = j / 2;

        save = arr[j];
        arr[j] = tmp;
        tmp = save;
    } while(j != i);
}

}

coder
  • 65
  • 2
  • 8
  • The case n=12 doesn't work. Using char arrays instead of int arrays , the example `cycle_leader("a0b1c2d3e4f5g6", 12)` gives `"ae15d04cg3bf26"`. – Paul Hankin May 10 '14 at 04:52
  • 1
    Thanks for your comment. Yes, it does not work for this case. – coder May 10 '14 at 06:39