given an array of integers in random order you have to find the minimum number of swaps to convert it to cyclic sorted array

前端 未结 4 603
野趣味
野趣味 2021-02-06 04:16

if an array is given in random order , you have to output the minimum number of swaps required to convert into cyclic sorted array.

e.g. array given is 3 5 4 2 1

相关标签:
4条回答
  • 2021-02-06 04:38

    Well, don't know if it is the best algorithm available, but I can think of a O(n^2) solution:

    First, ignore the possibility of the cyclic array. Let's solve a simpler problem: what is the minimum number of swaps to sort an array.

    Be careful here, because this isn't about sorting algorithms. A comparation-based sorting algorithm would have a worst-case of at least O(n log n). In this problem, the maximum number of swaps you need is n.

    Why? Because it's the maximum permutation cycle size you can achieve. The minimum number of swaps you need is exactly the permutation cycle size minus one. I mean you can represent any permutation of the array as a permutation cycle, e.g.:

    3 2 1 4 5 -> (2)(4)(5)(1 3)

    For the permutations cycles of size 1, you don't need any swap. For the permutation cycle of size 2, you need exactly 1 swap. This scales as:

    2 3 4 5 1 -> (1 2 3 4 5)

    Ignoring this array is already cyclic-sorted, this array is tottaly messed. To sort it normally, I would need 4 swaps, basically moving the 1 to it's normal position.

    Calculating the permutation cycles is pretty easy, it's just a matter of following the number to where it should be if the array was sorted. Using the previous examples

    3 2 1 4 5

    • Starts at A[0];
    • Because A[0]==3, and 3 would be the 3rd element in sorted array, follows to 3rd position;
    • Because A[2]==1, and 1 would be..., follows to 1st position. As we were already there here we have a cycle of size 2;

    • Starts again at next unvisited position (1)

    • A[1]==2 is in it's right position, so we don't need to do anything, here we have a cycle of size 1.

    • and so forth...

    This algorithm is O(n), but as we need to do this for the array starting in every possible position (because it is circular), we would do it n times, so, the entire algorithm is O(n^2).

    UPDATE; some python code to show my algorithm:

    def offset_swaps(A, S, offset):
        visited = [False]*len(A)
        swaps = 0
    
        for i in xrange(len(A)):
            if visited[i]: continue
    
            cycle, current = 0, i
            while not visited[current]:
                cycle += 1
                visited[current] = True
                current = (S[A[current]] + offset) % len(A)
    
            swaps += cycle - 1
    
        return swaps       
    
    def number_of_swaps(A):
        S = {x:i for i,x in enumerate(sorted(A))}
        min_swaps = len(A)
        for i in xrange(len(A)):
            min_swaps = min(min_swaps, offset_swaps(A, S, i))
        return min_swaps
    
    print number_of_swaps((3, 5, 4, 2, 1))
    
    0 讨论(0)
  • 2021-02-06 04:40

    Assuming:

    1. The array elements are the integers 1 to N.

    Steps:

    1. Allocate a second (histogram) array H of length N.
    2. In a single pass through the initial array A, for each index i increment H[ (A[i] - i) % N]
    3. In a single pass through H, identify the element R of H with the maximum count
    4. Clear H.
    5. Identify the number of Orbits in the original array under a rotation by R. (by stepping forward through H until H[i]=0, then stepping through the orbit for which A[i] is a member under the rotation R) setting H[i]=1 for each member of the orbit, and repeating until the element H[N-1] has been processed (counting the nubmer of orbits as you go). This is also O(N) as each element of A is visited exactly once.
    6. The required number of swaps = N - Orbits.

    This is O(N).

    Update: I have updated the algorithm to account for multiple orbits. In processing each orbit, the final swap places two elements instead of just 1.

    I suspect that the number of Orbits is invariant under any rotation, which would simplify the algorithm considerbly but would not affect it's complexity, which remains at O(N).

    0 讨论(0)
  • 2021-02-06 04:47

    I think the approach here should be - sort all the numbers into a helper array. Then for each cyclic shift calculate the number of swaps needed to get the original array to this cyclic shift. Choose the minimal of those.

    To find minimal number of swaps required to get array A to array B simply count the number of interchanged values(i.e. value a is on the left of value b in A but vice versa in array B). This problem is equivelent to counting the inversions in a given array and can be solved using modified merge sort again in O(n*log(n)).

    The complexity of my approach is O(n^2*log(n))(because you do a merge sort for all cyclic shifts of an array of size n).

    I can not think of a faster solution for your problem.

    0 讨论(0)
  • 2021-02-06 04:47
    def number_of_swaps(A):
        l=len(A)
        if l < 2:
            return 0
        S1={x:i for i,x in enumerate(A)}
        pos_of_0=S1[0]
        pos_of_N=S1[l-1]
        if pos_of_0 > 0:
            if pos_of_N != (l-1):
                if pos_of_N < pos_of_0:
                    n=(pos_of_0+(l-1)-pos_of_N-1)
                else:
                        n=(pos_of_0+(l-1)-pos_of_N)
            else:
                n=(pos_of_0)
        else :
            n=(l-pos_of_N-1)
        A.remove(0)
        A.remove(l-1)
        B=[x-1 for x in A ]
        return n+number_of_swaps(B)
    
    def min_number_of_swaps(A):
        B=sorted(A)
        swaps=[]
        for i in range(len(A)):
            if i == 0:
                C=B
            else:
                C=B[-i:]+B[0:len(A)-i]
    
            S = {x:i for i,x in enumerate(C)}
            D=[S[i] for i in A]
            swaps.append(number_of_swaps(D))
        return min(swaps)
    

    print min_number_of_swaps([8,5,7,1,2,4,3,6])

    7

    Above code isrecursive approach to solve the problem Complexity O(N^3)

    code has been edited to print only min number of swaps.

    0 讨论(0)
提交回复
热议问题