题解 | #数组中的逆序对#
数组中的逆序对
https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5
package main
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @return int整型
*/
//O(n)时间复杂度找开始变小的那个; O(logn)时间复杂度,递增有序序列。查找;找到目标值
//并归排序和二分查找很相似?
//O(n)空间复杂度 + O(nlogn)的时间复杂度; -> 并归排序 -> 递归? 循环?
//递归比循环好写
//
func InversePairs(nums []int) int {
// write code here
resCnt := 0
mergeSort(nums, 0, len(nums)-1, &resCnt)
return resCnt
}
// 并归+分治
// 这是并归排序的核心;合并两个有序数组; 并归排序的时候是数组本身内部进行变化;
func merge(nums []int, l, mid, r int, inverseCount *int) {
tmpSorted := make([]int, r-l+1) //数组从l->r这个区间之间有序的部分
si := 0 //排序好部分的遍历下标
i, j := l, mid+1
for ; i <= mid && j <= r; si++ {
if nums[i] < nums[j] {
tmpSorted[si] = nums[i]
i++
continue
}
tmpSorted[si] = nums[j]
j++
*inverseCount += mid - i + 1 //重点:理解这个公式;第一个数组当中前i个元素是比当前元素小的,剩下的是比当前元素大的。大的元素和当前元素就会组成一个逆序对;因此mid-i+1个
*inverseCount %= 1000000007
}
//剩余的部分都加回过去
for i <= mid {
tmpSorted[si] = nums[i]
si++
i++
}
for j <= r {
tmpSorted[si] = nums[j]
si++
j++
}
for t, v := range tmpSorted {
nums[l+t] = v
}
}
// 递归+合并
func mergeSort(nums []int, l, r int, inverseCount *int) {
mid := l + (r-l)/2
//排序左边;数组本身上面进行排序
if l < r {
mergeSort(nums, l, mid, inverseCount)
mergeSort(nums, mid+1, r, inverseCount)
merge(nums, l, mid, r, inverseCount)
}
}
查看7道真题和解析