leetcode面试题51. 数组中的逆序对

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

 

题解:

1.一列数组

2.找出数组中的逆序对

3.逆序对是指数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对

4.注意时间上限的限制严格

 

示例 1:

输入: [7,5,6,4]

输出: 5

限制:

0 <= 数组长度 <= 50000

 

解题思路:

对于没有严格时间限制的话,完全可以用两层循环解决

for( i=0; i<nums.length; i++ ){

        for( j=i+1; j<nums.length; j++ ){

            if( nums[j] < nums[i] ) sum++;

本题时间限制较为严格,虽然可以得到正确结果,但是数据量较大则超时

仔细分析元素比较过程可以发现,与二路归并排序合并为一路时元素比较过程是一样的,在运行时间上也有了保证。

 

class Solution {

    public int reversePairs(int[] nums) {

        if(nums==null||nums.length<1)

            return 0;//空元素,1个元素没有逆序对

        int[] copy=new int[nums.length];

        System.arraycopy(nums,0,copy,0,copy.length);

        return mergeSort(nums,copy,0,nums.length-1);}

    public int mergeSort(int[] nums,int[] copy,int start,int end) {

        if(start==end){//左右元素下标相等,说明区间内只有一个元素

            copy[start]=nums[start];//记录下元素

            return 0;}//没有逆序对,返回0

        int middle=(start+end)/2;//找中间位置

        int leftcount=mergeSort(copy,nums,start,middle);//左递归

        int rightcount=mergeSort(copy,nums,middle+1,end);//右递归

        int count=0;

        int i=middle,j=end;

        int lastindex=end;//区间一分为二,尾部元素开始向前移动,前后区间比较逆序对

        while(i>=start&&j>=middle+1){//在此时递归区间内

            if(nums[i]>nums[j]){//查找符合规则的逆序对

                copy[lastindex--]=nums[i--];//记录下逆序对左值

                count+=j-middle};//逆序对个数增加j-middle个

            else//如果不满足逆序对条件

                copy[lastindex--]=nums[j--];}//记录大数

        while(i>=start)//i没有到头,剩有小元素

            copy[lastindex--]=nums[i--];

        while(j>=middle+1) //j没有走到中间,后半区间剩大元素

            copy[lastindex--]=nums[j--];

        return count+leftcount+rightcount;

    }//一开始将整个数组元素一分为二,只比较了前半元素与后半元素可能的逆序对

}//在前/后半区间内也可能有逆序对,继续左右递归下去

Debug结果:

更多题解可前往公众号免费获取

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值