【剑指offer】51. 数组中的逆序对

题目描述

在这里插入图片描述

在这里插入图片描述

// 51. 数组中的逆序对

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

// 牛客
// 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数
// 字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。
// 并将P对1000000007取模的结果输出。 即输出P%1000000007


题解

 暴力法 ///

// 最直观的的做法是两个for循环全部遍历比对一轮
// 但是这种做法时间复杂度无法通过。

// 力扣
// 无法通过
class Solution {
    public int reversePairs(int[] nums) {
        int count = 0;
        if (nums.length < 2)
            return 0;
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[i] > nums[j])
                    count++;
            }
        }
        return count;
    }
}



 归并排序法 


// 牛客
// 根据题意,前大后小的两个数字构成一个逆序对。
// 直接写一个归并排序,在merge函数当nums[l]<nums[r]时,记录逆序对个数
// 运行时间:235ms
// 占用内存:33856KB
public class Solution {
	int count = 0;
	
    public int InversePairs(int[] nums) {
		int[] temp = new int[nums.length];
		mergesort(nums, 0, nums.length - 1, temp);
		return count % 1000000007;
    }
	
	private void mergesort(int[] nums, int left, int right, int[] temp) {
		if (left < right) {
			int mid = (left + right) / 2;
			mergesort(nums, left, mid, temp);
			mergesort(nums, mid + 1, right, temp);
			merge(nums, left, mid, right, temp);
		}
	}
	
	private void merge(int[] nums, int left, int mid, int right, int[] temp) {
		int l = left;
		int r = mid + 1;
		int t = 0;
		// 之前一直是nums[l]<=nums[r],l右移如果出现了nums[l]>nums[r],
	    // 说明l到mid的数,跟nums[r]都组成逆序对。(归并排序,左子数组元
	    // 素排序后还会在左子数组,右子数组元素排序后还会在右子数组)
		while (l <= mid && r <= right) {
			if (nums[l] <= nums[r])
				temp[t++] = nums[l++];
			else {
				temp[t++] = nums[r++];
				count += mid - l + 1;
				count = count % 1000000007;
			}
		}
		while (l <= mid) {
			temp[t++] = nums[l++];
		}
		while (r <= right) {
			temp[t++] = nums[r++];
		}
		t = 0;
		while (left <= right)
			nums[left++] = temp[t++];
	}
}

	int count = 0;
	
    public int InversePairs(int[] nums) {
		int[] temp = new int[nums.length];
		mergesort(nums, 0, nums.length - 1, temp);
		return count % 1000000007;
    }
	
	private void mergesort(int[] nums, int left, int right, int[] temp) {
		if (left < right) {
			int mid = (left + right) / 2;
			mergesort(nums, left, mid, temp);
			mergesort(nums, mid + 1, right, temp);
			merge(nums, left, mid, right, temp);
		}
	}
	
	private void merge(int[] nums, int left, int mid, int right, int[] temp) {
		int l = left;
		int r = mid + 1;
		int t = 0;
		while (l <= mid && r <= right) {
			if (nums[l] < nums[r])
				temp[t++] = nums[l++];
			else {
				temp[t++] = nums[r++];
				count += mid - l + 1;  // 如果nums[r] > nums[l]
				count = count % 1000000007;
			}
		}
		while (l <= mid) {
			temp[t++] = nums[l++];
		}
		while (r <= right) {
			temp[t++] = nums[r++];
		}
		t = 0;
		while (left <= right)
			nums[left++] = temp[t++];
	}
}


// 力扣
// 执行用时:37 ms, 在所有 Java 提交中击败了61.83%的用户
// 内存消耗:48.3 MB, 在所有 Java 提交中击败了37.82%的用户
class Solution {
    public int count = 0;
    public int reversePairs(int[] nums) {
        int[] temp = new int[nums.length];
        mergesort(nums, 0, nums.length - 1, temp);
        return count;
    }

    private void mergesort(int[] nums, int left, int right, int[] temp) {
        if (left< right) {
            int mid = (left + right) / 2;
            mergesort(nums, left, mid, temp);
            mergesort(nums, mid + 1, right, temp);
            merge(nums, left, mid, right, temp);
        }
    }

    private void merge(int[] nums, int left, int mid, int right, int[] temp) {
        int l = left;
        int r = mid + 1;
        int t = 0;
        while (l <= mid && r <= right) {
            if (nums[l] <= nums[r])
                temp[t++] = nums[l++];
            else {
                temp[t++] = nums[r++];
                count += mid - l + 1;
            }
        } 
        while (l <= mid)
            temp[t++] = nums[l++];
        while (r <= right)
            temp[t++] = nums[r++];

        t = 0;
        while (left <= right)
            nums[left++] = temp[t++];
    }
}






猜你喜欢

转载自blog.csdn.net/fisherish/article/details/114700029