leetcode 493

it2022-05-05  186

//利用归并排序来完成,归并排序可参考前面代码,归并排序可用来完成这类逆序对之类的问题,采用分治的思想,对于归并排序的代码不需要多改动,只需要在归并之前进行一次寻找操作,找出count的数量

class Solution {    private int count=0;    public int reversePairs(int[] nums) {         if(nums == null || nums != null && nums.length == 0)            return 0;        mergeSort(nums,0,nums.length-1);        return count;    }    public void mergeSort(int[] arr,int l,int r)    {        if(l>=r)            return ;        int mid=(l+r)/2;        mergeSort(arr,l,mid);        mergeSort(arr,mid+1,r);        merge(arr,l,mid,r);    }    public void merge(int[] arr,int l,int mid,int r)    {        int[] aux=new int[r-l+1];        for(int i=l;i<=r;i++)        {            aux[i-l]=arr[i];        }

//这几行代码就是寻找count的操作了,可以重新写个函数来完成这部分

//本人之前的错误一直是想要在归并的时候来进行判断count的数量,也就是在后面的for循环中比较两个数的值时,比如说第一个 i 指向的那个元素与右边 j 指向的那个元素比较时,还要多判断一下是否是两倍的大小,非常不容易写,我也一直没写出来,后来参考了一下别人的归并过程才发现,这部分完全可以独立出来写        int i=l,j=mid+1;        while(i<=mid&&j<=r)        {            long x=arr[i];            long y=2*(long)arr[j];            if(x>y)            {                count+=mid-i+1;                j++;            }            else{                i++;            }        }                i=l;        j=mid+1;        for(int k=l;k<=r;k++)        {            if(i>mid)            {                arr[k]=aux[j-l];                j++;            }            else if(j>r)            {                arr[k]=aux[i-l];                i++;            }            else  if(aux[i-l]<aux[j-l])            {                arr[k]=aux[i-l];                i++;            }            else {                arr[k]=aux[j-l];                j++;            }        }    }}

转载于:https://www.cnblogs.com/cold-windy/p/11195398.html


最新回复(0)