剑指 Offer 51. 数组中的逆序对

83 阅读1分钟

题目:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
算法:
[7,5,6,4] 只有 [7,5],[7,6],[7,4],[5,4],[6,4]5个逆序对,[5,6]不是逆序对。所以需要一个稳定的排序进行统计。
本地本质上是一个归并排序问题。
不交换nums和numsCopy的位置,可以用将排序好的numsCopy拷贝到nums中。

func reversePairs(nums []int) int {
    if len(nums) == 0 {
        return 0
    }
    copyNums := make([]int, len(nums))
    copy(copyNums, nums)
    fmt.Println(copyNums)
    return reversePairsCore(nums, copyNums, 0 , len(nums) - 1)
}

func reversePairsCore(nums, copyNums []int, start, end int) int {
    if start == end {
        copyNums[start] = nums[start]
        return 0
    }
    index := end
    length := (end - start) / 2
    leftParisCount := reversePairsCore(copyNums, nums, start, start + length)
    rightParisCount := reversePairsCore(copyNums, nums, start + length + 1, end)
    count := 0 
    i, j := start + length, end
    for ; i >= start && j >= start + length + 1; {
        if nums[i] > nums[j] {
            count = count + j - (start + length)
            copyNums[index] = nums[i]
            i --
            index -- 
        } else {
            copyNums[index] = nums[j]
            j -- 
            index --
        }
    } 

    for i >= start {
            copyNums[index] = nums[i]
            i --
            index -- 
    }
    for j >= start + length + 1 {
            copyNums[index] = nums[j]
            j -- 
            index --       
    }

    return leftParisCount + rightParisCount + count
}