题解 | #数组中的逆序对#
数组中的逆序对
https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5
<?php
/*
- 题目:[BM20 数组中的逆序对](https://www.nowcoder.com/share/jump/4163484761690943983774)
- 实现:
- 先把数组分隔成子数组
- 先统计出子数组内部的逆序对的数目
- 然后再统计出两个相邻子数组之间的逆序对的数目
- 时间复杂度: O(nlogn)
- 空间复杂度: O(n)
- 题目要求
- 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P
- 题目保证输入的数组中没有的相同的数字
- 要求:空间复杂度 O(n),时间复杂度 O(nlogn)O
- 并将P对1000000007取模的结果输出。 即输出P mod 1000000007
- 思路
- 归并排序:分治的思想,这个过程需要使用递归来实现
- 分:数组拆分
- 治:每个小数组如何处理
*/
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @return int整型
*/
function InversePairs( $nums )
{
$mod = 1000000007;
$count = 0;
$newNums = mergeSort($nums, $count);
return $count % $mod;
}
function mergeSort($arr, &$count)
{
// 分:分到元素个数为1
$size = count($arr);
if($size <= 1) {
return $arr;
}
// 再次拆分
$mid = $size >> 1;
$leftArr = array_slice($arr, 0, $mid);
$rightArr= array_slice($arr, $mid);
// 继续递归
$left = mergeSort($leftArr,$count);
$right = mergeSort($rightArr,$count);
// 合并
return merge($left, $right, $count);
}
// 在合并两个已排序子数组的过程中统计逆序对的数量
function merge($leftArr, $rightArr, &$count) {
$result = [];
$leftSize = count($leftArr);
$rightSize = count($rightArr);
$i = 0;
$j = 0;
// 合并两个数组
while($i < $leftSize && $j < $rightSize) {
if($leftArr[$i] <= $rightArr[$j]) {
$result[] = $leftArr[$i];
$i++;
} else {
$result[] = $rightArr[$j];
$j++;
// 左边比右边大,答案增加
// 如果是右边的数字更小,那么就是逆序对
$count += count($leftArr) - $i;
}
}
// 剩余的元素
// 左侧的数组
while ($i < $leftSize) {
$result[] = $leftArr[$i];
$i++;
}
// 右侧的数组
while ($j < $rightSize) {
$result[] = $rightArr[$j];
$j++;
}
return $result;
}
$nums = [1,2,3,4,5,6,7,0];
var_dump(InversePairs($nums));
$nums = [364,637,341,406,747,995,234,971,571,219,993,407,416,366,315,301,601,650,418,355,460,505,360,965,516,648,727,667,465,849,455,181,486,149,588,233,144,174,557,67,746,550,474,162,268,142,463,221,882,576,604,739,288,569,256,936,275,401,497,82,935,983,583,523,697,478,147,795,380,973,958,115,773,870,259,655,446,863,735,784,3,671,433,630,425,930,64,266,235,187,284,665,874,80,45,848,38,811,267,575];
var_dump(InversePairs($nums));
#每日刷题##每日刷题 文章被收录于专栏
刷题都刷不好,还能当程序员吗?

