• 剑指offer:逆序对


    这道题隐含的思想是二分法和归并排序。

    class Solution {
    public:
        int InversePairs(vector<int> data) {
           int length=data.size();
            if(length<=0)
                return 0;
           //vector<int> copy=new vector<int>[length];
           vector<int> copy;
           for(int i=0;i<length;i++)
               copy.push_back(data[i]);
           long long count=InversePairsCore(data,copy,0,length-1);
           //delete[]copy;
           return count%1000000007;
        }
        long long InversePairsCore(vector<int> &data,vector<int> &copy,int start,int end)
        {
           if(start==end)
              {
                copy[start]=data[start];
                return 0;
              }
           int length=(end-start)/2;
           long long left=InversePairsCore(copy,data,start,start+length);
           long long right=InversePairsCore(copy,data,start+length+1,end); 
            
           int i=start+length;
           int j=end;
           int indexcopy=end;
           long long count=0;
           while(i>=start&&j>=start+length+1)
              {
                 if(data[i]>data[j])
                    {
                      copy[indexcopy--]=data[i--];
                      count=count+j-start-length;          //count=count+j-(start+length+1)+1;
                    }
                 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;
        }
    };

    交换copy和data是因为:
    1.在每次的操作中,数值的比较都是采用当前传入函数中第一项,也就是data;比较的结果都存放到copy中;也就意味着此时copy中是经过此次调用的结果。
    2.从最底层返回时,进入了(start == end)的情形,data 和 copy 完全没有修改,此时copy和data还是一样的。
    3.进入倒数第二层时,程序进入上图26行以后部分,copy是部分排序后的新数组,data是旧数组。注意这里都是传值的调用,数组都是直接修改的。
    倒数第二层使用的copy其实是倒数第三层中的data,这就确保了倒数第三层进入26行以后时,数据比较使用的data是最新排序的数组。
    4. 倒数第三层将排序的结果存入copy中。程序在倒数第四层进入26行后,使用的data数组为刚刚倒数第三层中的最新排序的copy.
    5. 也就是说,在每次程序进入26行时,此时的data是最新的排序结果,copy是次新的结果。
    在最后一次进入26行以后时,copy为完整排序后的结果,data是次新的结果。
    然而这里第一个类内函数调用第二个函数时,data和copy的顺序没有改变,所以最后结果应该copy是完整排序的结果.data是差一步完成排序的结果。以输入[7,5,6,4], 最后的结果copy[4,5,6,7], data[5,7,4,6].

  • 相关阅读:
    二月12日
    十日冲刺
    十日冲刺
    十日冲刺
    十日冲刺
    十日冲刺
    十日冲刺
    十日冲刺
    一周进度条博客
    十天冲刺
  • 原文地址:https://www.cnblogs.com/a-little-v/p/10940105.html
Copyright © 2020-2023  润新知