码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-05-12 11:37:44      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:剑指offer   剑指offer 面试题36   数组中的逆序对   归并排序   

题目:

在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。例如在数组{7,5,6,4}中一共存在5对逆序对,分别是(7,6),(7,5),(7,4),(6,4),(5,4)


基本思想:

解法一:O(n^2)

最简单的想法就是遍历每一个元素,让其与后面的元素对比,如果大于则count++,但是这样的时间复杂度是O(n^2)。


解法二:O(nlogn)

归并排序思路:

技术分享

技术分享

例如7,5,4,6可以划分为两段7,5和4,6两个子数组

1.在7,5中求出逆序对,因为7大于5所以有1对

2.在6,4中求出逆序对,因为6大于4所以逆序对再加1,为2

3.对7,5和6,4进行排序,结果为5,7,和4,6

4.设置两个指针分别指向两个子数组中的最大值,p1指向7,p2指向6

5.比较p1和p2指向的值,如果大于p2,因为p2指向的是最大值,所以第二个子数组中有几个元素就有几对逆序对(当前有两个元素,逆序对加2,2+2=4),7>6,比较完之后将p1指向的值放入辅助数组里,辅助数组里现在有一个数字7,然后将p1向前移动一位指向5

6.再次判断p1和p2指向的值,p1小于p2,因为p1指向的是第一个子数组中最大值,所以子数组中没有能和当前p2指向的6构成逆序对的数,将p2指向的值放入辅助数组,并向前移动一位指向4,此时辅助数组内为6,7

7.继续判断p1(指向5)和p2(指向4),5>4,第二个子数组中只有一个数字,逆序对加1,4+1=5,为5对,然后将5放入辅助数组,第一个子数组遍历完毕,只剩下第二个子数组,当前只有一个4,将4也放入辅助数组,函数结束。辅助数组此时为4,5,6,7.逆序对为5.

    #include <iostream>
    using namespace std;  
      
    int InversePairsCore(int* data,int* copy,int start,int end)  
    {  
        if(start == end)  
        {  
            copy[start]=data[start];  
            return 0;  
        }  

        int length =(end - start)/2;  
        int left=InversePairsCore(copy,data,start,start+length);  
        int right=InversePairsCore(copy,data,start+length+1,end);  
      
        int i=start+length;  //i初始化为前半段最后一个数字的下标
        int j=end;           //j初始化为后半段最后一个数字的下标
        int indexCopy=end;  
        int count=0; 
		
        while(i>=start && j>= start+length+1)  
        {  
            if(data[i] >data[j])  
            {  
                copy[indexCopy--] =data[i--];  
                count+=j-start-length;  
            }  
            else  
            {  
                copy[indexCopy--]=data[j--];  
            }  
        }  
      
        for(;i>=start;--i)  
            copy[indexCopy--]=data[i];  
        for(;j>=start+length+1;--j)  
            copy[indexCopy--]=data[j];  
        return left+right+count;  
    }  

    int InversePairs(int* data,int length)  
    {  
        if(data == NULL || length <0)  
            return 0;  

        int* copy=new int[length];  
        for(int i =0;i<length;i++)  //辅助数组的初始化
            copy[i]=data[i];  

        int count=InversePairsCore(data,copy,0,length-1);  
        delete[] copy;  
        return count;  
    }  

    void main()  
    {  
        int a[4]={7,5,6,4};  
        int result=InversePairs(a,4);  
        cout<<result<<endl; 
    }  

时间复杂度为O(nlogn),但是要一个长度为n的辅助数组,所以空间复杂度为O(n)

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

标签:剑指offer   剑指offer 面试题36   数组中的逆序对   归并排序   

原文地址:http://blog.csdn.net/wtyvhreal/article/details/45664949

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!