不管全世界所有人怎么说,我都认为自己的感受才是正确的。无论别人怎么看,我绝不打乱自己的节奏。喜欢的事自然可以坚持,不喜欢的怎么也长久不了。
LeetCode:原题地址
题目要求
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例 1:
输入: [7,5,6,4]
输出: 5
限制:
0 <= 数组长度 <= 50000
思路
- 归并排序
const reversePairs = nums => {
// 记录逆序
let count = 0;
// 归并排序
const mergeSort = arr => {
// arr为一个值直接返回
if (arr.length < 2) return arr;
// 长度为2排序返回
if (arr.length === 2) {
if (arr[0] <= arr[1]) return arr;
// 记录逆序
count++;
return [arr[1], arr[0]];
}
// 获取二分位置
const mid = arr.length >> 1;
// 将左边部分排序
const left = mergeSort(arr.slice(0, mid));
// 将右边部分排序
const right = mergeSort(arr.slice(mid));
// 保存结果
const res = [];
// 两组的起始指针位置
let [leftIndex, rightIndex] = [0, 0];
// 循环直到两边遍历完
while (leftIndex < left.length || rightIndex < right.length) {
// left结束
if (leftIndex >= left.length) {
// 将剩余right添加到res
res.push.apply(res, right.slice(rightIndex));
// 跳出循环
break;
}
// right结束
if (rightIndex >= right.length) {
// 将剩余left添加到res
res.push.apply(res, left.slice(leftIndex));
// 跳出循环
break;
}
// 左值小
if (left[leftIndex] <= right[rightIndex]) {
// 将左值push
res.push(left[leftIndex]);
// 左下标右移
leftIndex++;
} else {
//右值小
// 将右值push
res.push(right[rightIndex]);
// 右下标右移
rightIndex++;
// 记录逆序(因为left是有序的,所以leftIndex开始都存在逆序)
count += left.length - leftIndex;
}
}
// 返回有序数组
return res;
};
mergeSort(nums);
return count;
};