数组中的逆序对

hard:数组中的逆序对


这是一道LeetCode中剑指offer的困难题:
链接:
https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/submissions/

题目:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数
示例:
输入: [7,5,6,4]
输出: 5

题解思路:
1)暴力法,可行是可行,但是太慢了,超过了时间限制,时间复杂度为O(n平方)
2)分治的思想:

  1. 先对数组不断的从中间分成两部分(两个区间)
  2. 分到区间个数只有一个的时候
  3. 然后开始合并,合并的时候,计算逆序对的个数
  4. 逆序对的个数,右边区间的数往temp中转数组中存放的时候,说明左边区间剩余的数都比该数大,那么会形成arrLeftIndex-left+1个逆序对。
  5. 注(arrLeftIndex为遍历左边区间的下标,left为左区间的第一个数的下标)
    例如:[5,7] 和 [4,6] 左、右区间
    arrLeftIndex = 0 arrRightIndex = 2
    temp[0] = arr[arrRightIndex]
    逆序对就有:1-arrLeftIndex+1个逆序对
    分别为:(5,4)和(7,4)

下面献上这道题的代码

class Solution {
    int res = 0;    //保存最终的逆序对个数
    //利用分治思想
    //每次合并的时候,去确定逆序对的个数有多少个
    //合并的时候,区间[left,mid]和区间[mid+1,right]
    //当有mid+1中需要放入到temp中转数组中的时候,
    //那么逆序对的个数就为左边区间指针(下标)-left+1个
    public int reversePairs(int[] nums) {
        mergeSort(nums,0,nums.length-1,new int[nums.length]);
        return res;
    }
    public void mergeSort(int[] arr,int left,int right,int[] temp){
        if(left<right){
            int mid = (left+right)/2;
            //向左递归
            mergeSort(arr,left,mid,temp);
            //向右递归
            mergeSort(arr,mid+1,right,temp);
            //合并,并算出逆序对
            int num = merge(arr,left,mid,right,temp);
            res+=num;
        }
    }
    //合并[left,mid]区间和[mid+1,right]区间,返回逆序对的个数
    public int merge(int[] arr,int left,int mid,int right,int[] temp){
        int inverseOrder = 0;   //计算合并的时候,逆序对的个数
        int l1 = left;
        int l2 = mid+1;
        int t = 0;
        while(l1<=mid&&l2<=right){
            if(arr[l1]<=arr[l2]){
                temp[t++] = arr[l1++];
            }else{
                inverseOrder+=(mid-l1+1);
                temp[t++] = arr[l2++];
            }
        }
        while(l1<=mid){
            temp[t++] = arr[l1++];
        }
        while(l2<=right){
            temp[t++] = arr[l2++];
        }
        t = 0;
        for(int i=left;i<=right;i++){
            arr[i] = temp[t++];
        }
        return inverseOrder;
    }

}
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页