JZ35 数组中的逆序对

一开始我以为两个数要求是相邻的,后来看了书才发现不一定是相邻的,实际上连题都没审清楚,

前面一个大于后面的数字,逆序对

例子中的逆序对有  1 0 ,2 0, 3 0,4 0,5 0,6 0,7 0   

思路一:暴力破解双循环        时间O(N^2),复杂度过高,值得注意的是,取余的操作需要在累加的过程中实现,防止累加值溢出,这也是题目为什么要求返回值取余

public class Solution {
    public int InversePairs(int [] array) {
        int num=0;
        for(int i=0;i<array.length;i++)
        {
            for(int j=i+1;j<array.length;j++)
            {
                if(array[i]>array[j])
                {
                    num++;
                    num%=1000000007;
                }
            }
        }
        return num;
    }
}

从前往后依次遍历的顺序行不通,那么我们能否从相邻的位置开始

思路二:归并排序

临时数组存在的意义

这里我举个例子,比如需要合并的两个有序区间为[3 4] 和 [1 2]
我们需要得到最后的结果为[1 2 3 4], 如果不需要额外的空间的话,是做不到的,
当比较1 和 3 的时候, 1 比 3 小,就会覆盖原来的位置。

正常的归并排序如下:

public class Solution {
    private int count=0;
    public int InversePairs(int [] array) {
        if(array==null||array.length==0)
            return 0;
        int[] tempList =new int[array.length];
        mergeSort(array,0,array.length-1,tempList);
        
    }
//递归调用函数
    private void mergeSort(int[] arrs,int left,int right,int[] tempList)
    {
        if(left>=right)//只有一个元素
            return;
        int mid=left+(right-left)/2;
        mergeSort(arrs,left,mid,tempList);
        mergeSort(arrs,mid+1,right,tempList);
        merge(arrs,left,right,mid,tempList);
    }
    //合并
    private void merge(int arrs[],int left ,int right,int mid,int[] tempList)
    {
        int i=left;
        int j=right;
        int t=0;
    //元素按序存入临时数组
        while(i<=left&&j<=right)
        {
            if(arrs[i]<arrs[j])
            {
                tempList[t++]=arrs[i++];
            }
            else
            {
                tempList[t++]=arrs[j++];
            }
        }
        //剩余数组压入
        while(i<=left)
        {
            tempList[t++]=arrs[i++];
        }
        while(j<=right)
        {
            tempList[t++]=arrs[j++];
        }
        //数组拷贝
        t=0;
        for(int k=left;k<right;k++)
        {
            arrs[k]=arrs[t++];
        }
    }
}

本题的归并:

public class Solution {
    private int count=0;
    public int InversePairs(int [] array) {
        if(array==null||array.length==0)
            return 0;
        int[] tempList =new int[array.length];
        mergeSort(array,0,array.length-1,tempList);
        return count;
        
    }
    private void mergeSort(int[] arrs,int left,int right,int[] tempList)
    {
        if(left>=right)//只有一个元素
            return;
        int mid=left+(right-left)/2;
        mergeSort(arrs,left,mid,tempList);
        mergeSort(arrs,mid+1,right,tempList);
        merge(arrs,left,right,mid,tempList);
    }
    //合并
    private void merge(int arrs[],int left ,int right,int mid,int[] tempList)
    {
        int i=mid;//左边最左端
        int j=right;//右边最左端
        int t=right;//临时数组尾索引
        while(i>=left&&j>=mid+1)//:两边从后往前排
        {
            if(arrs[i]>arrs[j])
            {
                tempList[t--]=arrs[i--];
                count=(count+j-mid)%1000000007;
            }
            else
            {
                tempList[t--]=arrs[j--];
            }
        }
        //剩余数组压入
        while(i>=left)
        {
            tempList[t--]=arrs[i--];
        }
        while(j>=mid+1)
        {
            tempList[t--]=arrs[j--];
        }
        //数组拷贝
        for(int k=right;k>=left;k--)
        {
            arrs[k]=tempList[k];
        }
    }
}

注意点:

本题临时数组是从后(right)往前压入的,每一次并的数组的范围left到right,拷贝的时候注意临时数组的边界【right到left】边界不是0,和索引0没关系0【这个地方卡半天】

正常的归并排序是压入临时数组是从索引0开始,所以拷贝从临时数组的索引0开始,但原数组相应的位置依然是left到right

时间O(nlog)   空间O(N)   空间换时间

思路看书,有序性的作用

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_40396568

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值