面试题36数组中的逆序对

面试题36数组中的逆序对

思路:最简单的方法。从头到尾遍历数组,每遍历一个数时,逐个比较该数字和它后面的数字的大小累加逆序对。

新颖的办法:先把数组分隔成子数组,先统计出子数组内部的逆序对的数目,再统计出两个相邻数组之间的逆序对的数目统计逆序对的过程是一个归并排序的过程在统计相邻数组的逆序对时,从大的往小的比,如果第一个数组的数字小于或等于第二个数组的数字则不构成逆序对,否则累加逆序对的个数。

函数接口 intinversePairs(int *data,int length);

Int  inversePairsCore(int *data,intlength,int start,int end,*temp)


#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
//思路:最简单的方法。从头到尾遍历数组,每遍历一个数时,逐个比较该数字和它后面的数字的大小累加逆序对。
//新颖的办法:先把数组分隔成子数组,先统计出子数组内部的逆序对的数目,再统计出两个相邻数组之间的逆序对的数目 统计逆序对的过程是一个归并排序的过程在统计相邻数组的逆序对时,从大的往小的比,如果第一个数组的数字小于或等于第二个数组的数字则不构成逆序对,否则累加逆序对的个数。

int inversePairsCore(int *a,int start,int end,int *temp);
int inversePairs(int *a,int length)
{
     if(a==NULL||length<=0)
	 {
	     return 0;
	 }
	 int start=0,end=length-1;
	 int *temp=new int[length];
	 int count=inversePairsCore(a,start,end,temp);
	// delete [] temp;
	 return count;
}
int inversePairsCore(int *a,int start,int end,int *temp)//统计逆序对的个数需要辅助数组 同时对原数组进行了排序
{
    if(start==end)
	{
	    return 0;
	}
	else if(start<end)
	{
	    int mid=(start+end)/2;
		int left=inversePairsCore(a,start,mid,temp);//相当于子数组内部的逆序队数目
		int right=inversePairsCore(a,mid+1,end,temp);//相当于子数组内部的逆序队数目
		//以下为将一维数组中前后相邻的两个有序序列归并为一个有序序列   从后向前比较  以下程序相当于统计相邻子数组之间的逆序队数
		int i=mid,j=end;
		int k=end-start,count=0; //注意k的从最大的往下降
		while(i>=start&&j>=mid+1)//此处注意从大的往小的比 注意是j>=mid+1 
		{
		    if(a[i]>a[j])//有逆序对
			{
			   temp[k--]=a[i--];
			   count=count+j-(mid+1)+1;//累加逆序对
			}
			else
			{
			   temp[k--]=a[j--];
			}
		}
		while(i>=start)
		{
		    temp[k--]=a[i--];
		}
		while(j>=mid)
		{
		    temp[k--]=a[j--];
		}
		for(i=0;i<end-start+1;i++)
		{
		     a[start+i]=temp[i];
		}
		return left+right+count;
	}
}
int main()
{
	int a[]={7,5,6,4};
	int length=sizeof(a)/sizeof(a[0]);
	
	int count=inversePairs(a,length);
	cout<<"逆序队个数为:"<<count<<endl;
	for(int i=0;i<length;i++)
	{
	    cout<<a[i]<<',';
	}
	cout<<endl;
   return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值