剑指 Offer 51. 数组中的逆序对

剑指 Offer 51. 数组中的逆序对

  • 前言
  • 一、暴力求解
  • 二、归并排序后再求解


前言

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
剑指 Offer 51. 数组中的逆序对_第1张图片


一、暴力求解

暴力求解依然可以用来解这道题目,但是问题在于会超时,因为时间复杂度过大

public int reversePairs(int[] nums) {
        int cnt = 0;
        int len = nums.length;
        for (int i = 0; i < len - 1; i++) {
            for (int j = i + 1; j < len; j++) {
                if (nums[i] > nums[j]) {
                    cnt++;
                }
            }
        }
        return cnt;
    }

在这里插入图片描述

二、归并排序后再求解

图片和部分内容来自:
剑指 Offer 51. 数组中的逆序对(归并排序,清晰图解)
暴力解法、分治思想、树状数组

分: 不断将数组从中点位置划分开(即二分法),将整个数组的排序问题转化为子数组的排序问题;

治: 划分到子数组长度为 1 时,开始向上合并,不断将 较短排序数组 合并为 较长排序数组,直至合并至原数组时完成排序;

合并阶段 本质上是 合并两个排序数组 的过程,而每当遇到 左子数组当前元素 > 右子数组当前元素 时,意味着 「左子数组当前元素 至 末尾元素」 与 「右子数组当前元素」 构成了若干 「逆序对」

	int cnt = 0;//需要不断累加,因此不能是局部变量,应该是个全局都可以使用的变量

    public int reversePairs(int[] nums) {
        mergeSort(nums,0,nums.length - 1,cnt);
        return cnt;
    }

    public void mergeSort(int[] nums, int left, int right, int cnt){
        if(left >= right){
            return ;
        }
        int mid = (right - left)/2 + left;
        mergeSort(nums, left, mid, cnt);
        mergeSort(nums, mid + 1, right, cnt);
        merge(nums, left, mid, right);
    }

    public void merge(int[] nums, int left, int mid, int right){
        int temp[] = new int[right - left + 1];
        int i = left;
        int j = mid + 1;
        int k = 0;
        while(i <= mid && j <= right){
            if(nums[i] > nums[j]){
                cnt = cnt + mid - i + 1;
                temp[k] = nums[j];
                k++;
                j++;
            }else{
                temp[k] = nums[i];
                k++;
                i++;
            }
        }
        while(i <= mid){
            temp[k] = nums[i];
            i++;
            k++;
        }
        while(j <= right){
            temp[k] = nums[j];
            j++;
            k++;
        }
        for(int m = 0; m < right - left + 1; m++){
            nums[m + left] = temp[m];
        }
    }

剑指 Offer 51. 数组中的逆序对_第2张图片
剑指 Offer 51. 数组中的逆序对_第3张图片

你可能感兴趣的:(算法,排序算法,leetcode)