《剑指offer》:数组中的逆序对——算法讲解

《剑指offer》:数组中的逆序对——算法讲解

例如在数组{7,5,6,4} 中,一共存在5个逆序对,分别是(7,6)、(7,5)、(7,4)、(6,4)和(5,4)。

牛客网连接:https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5?tpId=13&tqId=11188&tPage=2&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking


方法一:顺序扫描整个数组。

每到一个数就从头到尾计算其他数到这里的逆序对数,复杂度是O(n2),由最上的输入描述,复杂度是不可忍受的

方法二:先比较两个相邻的数字

来自《剑指offer》第二版

  • 每扫描到一个数字的时候,不能拿它和后面的每一个数字进行比较
  • 考虑先比较两个相邻的数字(如下图)

《剑指offer》:数组中的逆序对——算法讲解

  • (a)(b)(c)三步都很容易理解,(c)统计逆序对也很容易【记得要排序】,难点在于(d)。
  • 如何对{5,7}  {4,6},计算出逆序对。 只要重复递归步骤(d)便可计算出所有的逆序对数。

针对步骤(d):合并子数组 && 统计逆序对

《剑指offer》:数组中的逆序对——算法讲解

如上图:

  • 先用两个指针 P1、P2 指向两个子数组的末尾(P1 指向7,P2指向 6)
  • 比较 P1、P2 指向的数的大小
  • 如果 P1->num 大于  P2->num(如上图a情况  7>6)构成逆序对,且逆序对的数目 等于 第二个子数组中从左到指针处所有数字的个数。【图a是两对,图c是一对】
  • 如果 P1->num 小于  P2->num(如上图b情况  5<6)不构成逆序对
  • 注意:每次比较的时候,把较大的数字,从后往前放在另外一个数组中,以确保计算逆序对后得到一个排序好的数组

其实就是归并排序:复杂度为O(nlogn)

关于归并排序:https://blog.****.net/qq_39883358/article/details/83149825