剑指offer面试题36:数组中的逆序对

来源:互联网 发布:索福瑞实时数据 编辑:程序博客网 时间:2024/05/14 09:20

题目:数组中两个数字如果前面一个数大于后面一个数,则这两个数字组成一个逆序对,输入一个数组,求数组逆序对总数。

例如:数组{7,1,9,10,2,3,4}中,一共存在10个逆序对,分别是{7,1}、{7,2}、{7,3}、{7,4}、{9,2}、{9,3}、{9,4}、{10,2}、{10,3}、{10,4}。

思路1:对数组中的每个数字,扫描它后面的数字,如果后面的数比这个数小,则存在逆序对,这样将数组扫描完需要的时间复杂度是O(N^2)
思路2:利用归并排序,归并排序的核心算法中,合并两个前后两个序列的时候,可以统计这两个前后序列之间的逆序对,再加上每个序列的逆序对,就是一共的逆序对

    //每个序列的逆序对,可以用递归分治

    //举个例子,原序列是9 10 2 4 3

   //最后要合并的两个左右序列是2 9 10 和3 4

   //刚开始a[i]=2 a[j] = 3,a[i]<a[j]不存在逆序对,将i++,a[i]->9

   //这时候a[i]>a[j],存在逆序对,并且前一个序列中a[i+1...mid]因为是已经排序的,

   //后面的每个数肯定也大于a[i],当然也大于a[j],当然也和a[j]成逆序对,这时候的逆序对的个数应该为mid-i+1

  

  //先把数组分隔成子数组,先统计出子数组内部的逆序对的数目,然后再统计出两个相邻子数组之间的逆序对的数 目。在统计逆序对的过程中,还需要对数组进行排序。

 //举个例子:7 5 6 4

 //先把数组分解成两个长度为2的子数组{7 5}和{6 4},再把这两个子数组分别拆成两个长度为1的子数组{7}和{5}、{6}和{4},接下来一边合并相邻的子数组,一边统计逆序对的数目。

 //在第一对长度为1的子数组{7}、{5}中7大于5,因此{7,5}是一个逆序对。同样在第二对长度为1的子数组{6}、{4}中也有一个逆序对{6,4}。

 //由于已经统计过这两对子数组内部逆序对,因此需要对这两对子数组排序,以免在以后的统计过程中再重复统计。

//代码待续......

 

原创粉丝点击