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 604
野趣味
野趣味 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))
    

提交回复
热议问题