光影切割问题,经过分析之后,可以简化为一个求逆序数的问题,当然求逆序数可以用非常暴力的O(N^2)的解法,这个结果肯定不会让面试官满意的,求逆序对可以采用分治思想,先求前N/2的逆序对数量,然后求后N/2的逆序对的数量。
具体代码如下:
#include <iostream>
using namespace std;
int getreverse(int A[],int mstart,int mend);
int main ()
{
int A[] = {3,1,4,2,7,6,9,5};
cout << getreverse(A,0,7);
}
int getreverse(int A[],int mstart,int mend)
{
if(mstart < mend)
{
int mid = (mstart + mend)>>1;
int ileft = getreverse(A,mstart,mid);//左边部分的逆序对
int iright = getreverse(A,mid+1,mend);//右边部分的逆序对
int *mtp = new int[mend-mstart+1];
int k = 0;
int i = mstart;
int j = mid+1;
int itmp = 0;
while (i <= mid && j <= mend)
{
if(A[i] > A[j])
{
itmp += (mid-i+1);//出现逆序对
mtp[k++] = A[j++];
}
else
{
mtp[k++] = A[i++];
}
}
while (i <= mid)
{
mtp[k++] = A[i++];
}
while (j <= mend)
{
mtp[k++] = A[j++];
}
k = 0;
for(int i = mstart;i <= mend;i ++)
{
A[i] = mtp[k++];
}
delete []mtp;
return ileft+iright+itmp;
}
else
{
return 0;
}
}
其他的方法可以参照: