数组中的逆序对

/*
 * 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。
 * 并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
    对于%50的数据,size<=10^4
    对于%75的数据,size<=10^5
    对于%100的数据,size<=2*10^5
示例1
输入
1,2,3,4,5,6,7,0
输出  :  7
 */

思路:其实就是进行一个归并排序的过程

例如:(4,2,6,1)

先分解成(4,2),(6,1)再分解成4,2,6,1已经是最小单元

对4,2进行归并,指针1指向4,指针2指向2,4>2,产生1对逆序对           count=1

同理,6,1产生1对逆序对       count=2

接下来对(2,4),(1,6)归并

指针1指向2,指针2指向1,2>1,那么显然左边的有序序列(2,4)中的所有元素都会比1大,产生了左边序列长度个逆序对,此处为2个,此时count=4

然后指针2后移指向6,显然2<6,不产生逆序对,然后指针1后移指向4,4<6不产生逆序对,这时归并也结束了得到(1,2,4,6),count=4

所以整个方法是建立在归并排序上的。下面附上代码

public class Solution {
    static int count=0;
	public static int InversePairs(int [] array) {
        if(array.length==0)
            return 0;
		mysort(array);
		return count%1000000007;
    }
	public static int[] mysort(int[] a)  //为归并排序写的统一接口
	{
        if(a.length==0)
			return null;
		return sort(a,0,a.length-1);
	}
	private static int[] sort(int[] a,int left,int right)  //递归解决归并
	{
		int mid=(left+right)/2;
		if(left<right)
		{
			sort(a,left,mid);
			sort(a,mid+1,right);
			guibing(a,left,mid,right);
		}
		return a;
	}
	private static int[] guibing(int[] a,int left,int mid,int right) //归并两个有序序列
	{
		int i=left;
		int j=mid+1;
		int k=0;
		int[] temp=new int[right-left+1];
		while(i<mid+1&&j<=right)
		{
			if(a[i]<=a[j])
			{
				temp[k++]=a[i++];
			}
			else
			{
				temp[k++]=a[j++];
				count+=mid-i+1;        
                       count=count%1000000007;//除去此处count相关代码就是完完全全的归并排序
			}
		}
		while(i<mid+1)
		{
			temp[k++]=a[i++];
		}
		while(j<=right)
		{
			temp[k++]=a[j++];
		}
		k--;
		while(true)
		{
			a[right--]=temp[k--];
			if(k<0)
				break;
		}
		return a;
	}
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值