题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述
题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
示例
输入
1,2,3,4,5,6,7,0
输出
7
思路
1.可以通过移动数字发现,计算逆序对的方式和归并排序的merge操作有相似之处。
2.当进行merge操作时,若左边数组的元素大于右边数组的某一元素时,说明存在mid-left-l个逆序对。
- 因为左边数组和右边数组都是排好序的
- l索引代表左边数组当前索引
- 可以参照下图,理解归并过程中的计算逻辑。
Java代码实现
public class Solution {
private int count = 0;
public int InversePairs(int [] array) {
if(array != null){
mergeSort(array,0,array.length-1);
}
return count;
}
private void mergeSort(int[] array,int left,int right){
if(left >= right){
return ;
}
int mid = (left + right)/2;
mergeSort(array,left,mid);
mergeSort(array,mid+1,right);
merge(array,left,mid+1,right);
}
private void merge(int[] array,int left,int mid,int right){
int[] leftArray = new int[mid-left];
int[] rightArray = new int[right-mid+1];
for(int i=left;i<mid;i++){
leftArray[i-left] = array[i];
}
for(int i=mid;i<=right;i++){
rightArray[i-mid] = array[i];
}
int l = 0;
int r = 0;
int k = left;
while(l < leftArray.length && r < rightArray.length){
if(leftArray[l] > rightArray[r]){
array[k++] = rightArray[r++];
count = (count + mid - left- l)%1000000007;
}else{
array[k++] = leftArray[l++];
}
}
while(l < leftArray.length){
array[k++] = leftArray[l++];
}
while(r < rightArray.length){
array[k++] = rightArray[r++];
}
}
}
Golang代码实现
var res int = 0
func InversePairs(nums []int) int {
mergeOuter(nums,0,len(nums)-1)
return res
}
func mergeOuter(nums[] int,left int,right int){
if left >= right{
return
}
mid := (left + right)/2
mergeOuter(nums,left,mid)
mergeOuter(nums,mid+1,right)
merge(nums,left,mid+1,right)
}
func merge(nums []int,left int,mid int,right int){
leftArray := make([]int,mid-left)
rightArray := make([]int,right-mid+1)
for i:=left; i<mid;i++{
leftArray[i-left] = nums[i];
}
for i:=mid; i<=right;i++ {
rightArray[i-mid] = nums[i];
}
k := left
l,r := 0,0
for l<len(leftArray) && r<len(rightArray) {
if leftArray[l] > rightArray[r]{
nums[k] = rightArray[r]
k++
r++
res = (res + mid - left - l)%1000000007
}else{
nums[k] = leftArray[l]
k++
l++
}
}
for l<len(leftArray) {
nums[k] = leftArray[l]
k++
l++
}
for r<len(rightArray){
nums[k] = rightArray[r]
k++
r++
}
}
有疑问加站长微信联系(非本文作者)