Counting inversions in an array

前端 未结 30 2430
死守一世寂寞
死守一世寂寞 2020-11-22 04:14

I\'m designing an algorithm to do the following: Given array A[1... n], for every i < j, find all inversion pairs such that A[i] > A[j]

30条回答
  •  耶瑟儿~
    2020-11-22 04:41

    Implementation of counting inversions in an array with merge sort in Swift:

    Note that the number of swaps is incremented by

    nSwaps += mid + 1 - iL 
    

    (which is the relative length of the left side of the array minus the index of the current element in the left side)

    ... because that is the number of elements which the element in the right side of the array had to skip over (# of inversions) to become sorted.

    func merge(arr: inout [Int], arr2: inout [Int], low: Int, mid: Int, high: Int) -> Int {
        var nSwaps = 0;
    
        var i = low;
        var iL = low;
        var iR = mid + 1;
    
        while iL <= mid && iR <= high {
            if arr2[iL] <= arr2[iR] {
                arr[i] = arr2[iL]
                iL += 1
                i += 1
            } else {
                arr[i] = arr2[iR]
                nSwaps += mid + 1 - iL
                iR += 1
                i += 1
            }
        }
    
        while iL <= mid {
            arr[i] = arr2[iL]
            iL += 1
            i += 1
        }
    
        while iR <= high {
            arr[i] = arr2[iR]
            iR += 1
            i += 1
        }
    
        return nSwaps
    }
    
    func mergeSort(arr: inout [Int]) -> Int {
        var arr2 = arr
        let nSwaps = mergeSort(arr: &arr, arr2: &arr2, low: 0, high: arr.count-1)
        return nSwaps
    }
    
    func mergeSort(arr: inout [Int], arr2: inout [Int], low: Int, high: Int) -> Int {
    
        if low >= high {
            return 0
        }
    
        let mid = low + ((high - low) / 2)
    
        var nSwaps = 0;
        nSwaps += mergeSort(arr: &arr2, arr2: &arr, low: low, high: mid)
        nSwaps += mergeSort(arr: &arr2, arr2: &arr, low: mid+1, high: high)
        nSwaps += merge(arr: &arr, arr2: &arr2, low: low, mid: mid, high: high)
    
        return nSwaps
    }
    
    var arrayToSort: [Int] = [2, 1, 3, 1, 2]
    let nSwaps = mergeSort(arr: &arrayToSort)
    
    print(arrayToSort) // [1, 1, 2, 2, 3]
    print(nSwaps) // 4
    

提交回复
热议问题