2

Suppose I have an array like this: [5 4 1 2 3]

And I want to compute the minimum switch I have to make to sort the unsorted permutation.

Now the answer is 7 in this case. Just move 4 and 5 to the right, or move 1, 2, 3 to the left.

The irony though, is that I used [4 5 1 2 3] in my notes, which gives 6, and mislead myself and make a fool of myself.

Steps:

[5 1 4 2 3] // step 1

[1 5 4 2 3] // step 2

[1 5 2 4 3] // step 3

[1 2 5 4 3] // step 4

[1 2 5 3 4] // step 5

[1 2 3 5 4] // step 6

[1 2 3 4 5] // step 7

I've thought of things like having an array that keep the offset needed, and for each loop, just look for the switch that moves the whole thing closer to goal.

But that just seem too slow, any ideas?

EDIT: from comment: are the members of the array guaranteed to completely belong to {1..N} set for an array of size N, without repeating numbers?

Nope. It's not guaranteed not to repeat or being in [1...n] for array sized N.

UPDATE:

There are two solutions to this particular problem, once is slower but more straightforward bubblesort, another is the faster but less straightforward mergesort.

With bubblesort, you basically count the number of switches when running the algorithm.

With mergesort, it's a bit more trickier, but the counting happens when merging. When the array is already merged, the count should yield 0 as no switches will be needed to sort this array. With bubblesort, you count the switches when you push the largest or the smallest number to the left or right. With mergesort, you count switches when merging. I bit of hand writing brute forcing will get you there.

Shane Hsu
  • 7,937
  • 6
  • 39
  • 63
  • How did you determine it's 7? – nmclean Sep 04 '13 at 01:17
  • This totally depends on the algorithm you use. The better, the less unnecessary switches to be done. Observe: [video](http://youtu.be/vxENKlcs2Tw?t=1m54s) – smac89 Sep 04 '13 at 02:03
  • @nmclean why wouldn't it be 7? I think it is as I detailed the step. Can you find another way with lower switch count? – Shane Hsu Sep 04 '13 at 04:30
  • @Smac89: I understood Shane Hsu wants to find the minimal number of switches (i.e. the number an optimal alorithm would need). – undur_gongor Sep 04 '13 at 09:27
  • are you sure it's 6? It requires 7 steps: [5 4 1 2 3] [4 5 1 2 3] [4 1 5 2 3] [4 1 2 5 3] [4 1 2 3 5] [1 4 2 3 5] [1 2 4 3 5] [1 2 3 4 5] – justhalf Sep 04 '13 at 09:34
  • It requires seven steps, and not six, because 4 and 5 have to also switch places, not just traverse to their destination. – Dialecticus Sep 04 '13 at 09:52
  • 2
    Question: are the members of the array guaranteed to completely belong to {1..N} set for an array of size N, without repeating numbers? – Dialecticus Sep 04 '13 at 09:55
  • @Dialecticus Nope. And I've edited the question. Any idea? – Shane Hsu Sep 04 '13 at 09:57
  • @Dialecticus I am thinking if repeating number would ruin bubblesort solution. – Shane Hsu Sep 04 '13 at 09:58
  • So the array can also be [9 8 1 2 3], or even [8 8 1 2 3]? – Dialecticus Sep 04 '13 at 09:58
  • @Dialecticus sure. The problem is originally "how to rearrange vases most efficiently according to size? You can only switch nearby vases" – Shane Hsu Sep 04 '13 at 10:01
  • Having repeating number would not ruin the solution, as it won't make unnecessary switch (since we switch only if the number on the left is strictly greater than the number on the right) – justhalf Sep 04 '13 at 10:06
  • Think so too. Tests also say so. Didn't this would really be as simple as bubble sort. Always thought bubble sort would made unnecessary moves. Thanks anyway. – Shane Hsu Sep 04 '13 at 10:14
  • @ShaneHsu I didn't mean it's not 7. But if you can answer the question of *how* you determined it, you can most likely translate your thought process into an algorithm. – nmclean Sep 04 '13 at 11:48
  • @nmclean I see. Well, I hand crack it without any algorithm in mind for that, I thought it could be more of a DP/optimization thing, little did I know that it's just bubble sort. So, ya... – Shane Hsu Sep 04 '13 at 13:48

2 Answers2

3

What you're actually looking for is calculating the number of inversions in a sequence.

This can be done in O(n*logn) using mergesort, for example.

Here you have an article about this subject, looks quite understandable.

Some more links:

Community
  • 1
  • 1
welter
  • 156
  • 4
2

This looks suspiciously similar to bubble sort, in which you need up to n^2 movements.

And the interesting fact is that, simple bubble sort actually achieves your goal to find the minimum number of switches! (proof below)

In that case, we don't need to further improve algorithms using double loops, and it's actually possible using double loops (in C++):

int switch = 0;
for(int repeat=0; repeat<n; repeat++){
    for(int j=0; j<n-repeat; j++){
        if(arr[j]>arr[j+1]){
            int tmp = arr[j];
            arr[j] = arr[j+1];
            arr[j+1] = tmp;
            switch = switch + 1
        }
    }
}

The switch is the result.
arr is the array containing the numbers.
n is the length of the array.

Prove that this produces minimum number of switch:

First, we note that the bubble sort essentially moves the highest element into the rightmost position in the array at each iteration (outer loop)

Note that switching the highest element with any other element in the process does not change the relative order of other elements. And also any other switch operations done in between our attempt to move the highest element to its position will not change the number of switch required to move the highest element to place. And so we can interchange the switch operations such that the highest element is always switched first until it gets into position. Therefore switching the highest element into its position one at a time is optimum.

justhalf
  • 8,960
  • 3
  • 47
  • 74
  • Have you run this for my test case? Does switch = 7? – Shane Hsu Sep 04 '13 at 04:29
  • Yes, it is. What programming language do you normally use? – justhalf Sep 04 '13 at 04:45
  • C++. And I don't hunk bubble sort present the most optimal way to switch sort it. – Shane Hsu Sep 04 '13 at 09:22
  • To move 4 and 5 to the right it requires 7 steps. [54123]-[45123]-[41523]-[41253]-[41235]-[14235]-[12435]-[12345] – justhalf Sep 04 '13 at 09:23
  • 1
    Yes, you're right. I'm stupid. I should rot in hell. Anyway, I've written something myself, http://ideone.com/iP3ypY And it seems bubblesort really is the solution! Thank you for taking so much time! – Shane Hsu Sep 04 '13 at 09:51
  • Your bubble sort only switches adjacent numbers. The original question does not have this constraint, so I doubt that a bubble sort is the optimum solution. – Peter Webb Sep 05 '13 at 08:47
  • If you read carefully, you will realize that the OP actually thinks of switch as "switching adjacent numbers", as evident from the example. – justhalf Sep 05 '13 at 08:51