题目描述


题解
//////////////////////////////// 暴力法 ///////////////////////////////
// 最直观的的做法是两个for循环全部遍历比对一轮
// 但是这种做法时间复杂度无法通过。
// 力扣
// 无法通过
class Solution {
public int reversePairs(int[] nums) {
int count = 0
if (nums.length < 2)
return 0
for (int i = 0
for (int j = i + 1
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
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++]
}
}