493. 翻转对
给定一个数组 nums ,如果 i < j 且 nums[i] > 2*nums[j] 我们就将 (i, j) 称作一个重要翻转对。
你需要返回给定数组中的重要翻转对的数量。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-pairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
当移动一个指针位置时,该位置的情况是否已经全部考虑到?
比如
while (p1 <= mid && p2 <= r) {
if (nums[p1] > nums[p2]) {
if (nums[p1] <= 2L * nums[p2]) {
ret += (r - p2 + 1);
}
helper[index++] = nums[p1++];
} else {
helper[index++] = nums[p2++];
}
}
中移动 p1的方式是不合理的,因为此时(p1, p2)不满足要求,可能是p2太大,即后面的元素可能有更小的p2‘使得(p1, p2')满足要求。
class Solution {
private int[] helper;
private int mergeSort(int[] nums, int l, int r) {
if (l >= r) {
return 0;
}
int ret = 0;
int mid = (l + r) >> 1;
ret += mergeSort(nums, l, mid);
ret += mergeSort(nums, mid + 1, r);
int p1 = l, p2 = mid + 1, index = l;
while (p1 <= mid) {
while (p2 <= r && nums[p1] <= 2L * nums[p2]) {
p2++;
}
ret += (r - p2 + 1);
p1++;
}
p1 = l;
p2 = mid + 1;
while (p1 <= mid && p2 <= r) {
if (nums[p1] > nums[p2]) {
helper[index++] = nums[p1++];
} else {
helper[index++] = nums[p2++];
}
}
while (p1 <= mid) {
helper[index++] = nums[p1++];
}
while (p2 <= r) {
helper[index++] = nums[p2++];
}
System.arraycopy(helper, l, nums, l, r - l + 1);
return ret;
}
public int reversePairs(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
this.helper = new int[nums.length];
return mergeSort(nums, 0, nums.length - 1);
}
}
心之所向,素履以往 生如逆旅,一苇以航