光影切割问题-求逆序对@编程之美

光影切割问题,经过分析之后,可以简化为一个求逆序数的问题,当然求逆序数可以用非常暴力的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;
    }
}


其他的方法可以参照:

http://blog.csdn.net/lonelycatcher/article/details/7907333

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值