面试题29:数组中的逆序对
来源:互联网 发布:js containskey 编辑:程序博客网 时间:2024/05/14 15:04
暴力方法:扫描数组中的每个数,逐个比较该数字和其后面的数字的大小,若后面的数字比其小,则是一个逆序对。
改进方法:先把数组分割成子数组,先统计出子数组内部的逆序对数,然后再统计出两个相邻子数组见的逆序对数。统计逆序对的过程中,需要对数组进行排序。显然排序过程是归并排序。时间复杂度由O(n^2)降为O(nlogn),但需要O(n)的空间复杂度,是用空间换时间的做法。
代码:
#include "stdafx.h"#include <iostream>#include <assert.h>using namespace std;//合并两个排好序的数组nArr[nStart, nMid]和nArr[nMid+1, nEnd]void Merge(int nArr[], int nStart, int nMid, int nEnd, int *pTemp, int &nCount){//设置两个游标指向两个子数组中的元素,初始状态指向尾元素int nCur1 = nMid;int nCur2 = nEnd;int nTempIndex = nEnd;//同时遍历两个子数组,依次放入临时数组中while ((nCur1 >= nStart) && (nCur2 >= nMid + 1)){if (nArr[nCur1] > nArr[nCur2]){nCount += nCur2 - nMid;//注意此处代码pTemp[nTempIndex--] = nArr[nCur1--];}else{pTemp[nTempIndex--] = nArr[nCur2--];}}while (nCur1 >= nStart){pTemp[nTempIndex--] = nArr[nCur1--];}while (nCur2 >= nMid+1){pTemp[nTempIndex--] = nArr[nCur2--];}//将临时数组中的元素赋值到原数组中 for (int i=nStart; i<=nEnd; i++) { nArr[i] = pTemp[i]; }}//归并排序void ReverseOrderCount(int nArr[], int nStart, int nEnd, int *pTemp, int &nCount){assert(nArr != NULL && nStart >= 0 && nEnd >= 0);if (nStart < nEnd){int nMid = (nStart + nEnd) >> 1;ReverseOrderCount(nArr, nStart, nMid, pTemp, nCount);//对数组的前半部分进行归并排序ReverseOrderCount(nArr, nMid+1, nEnd, pTemp, nCount);//对数组的后半部分进行归并排序Merge(nArr, nStart, nMid, nEnd, pTemp, nCount);//合并两个排好序的数组}}//求数组中的逆序对int ReverseOrderCount(int nArr[], int nLength){ if (nArr == NULL || nLength < 0) {return 0; }//申请一个长度相等的临时数组int *nTemp = new int [nLength];int nCount = 0;ReverseOrderCount(nArr, 0, nLength-1, nTemp, nCount);delete[] nTemp;nTemp = NULL;return nCount;}//打印数组中的逆序对数和排好序的数组 void PrintMessage(int nArr[], int nLength) { cout << "逆序对的个数:" << ReverseOrderCount(nArr,nLength) << endl; cout << "排好序的数组:"; for (int i=0; i<nLength; i++) { cout << nArr[i] << " "; } cout << endl << endl; }int _tmain(int argc, _TCHAR* argv[]){//未排好序的数组int nArr1[5] = {7,5,6,4,8};PrintMessage(nArr1, 5);//递增数组int nArr2[5] = {4,5,6,7,8};PrintMessage(nArr2, 5);//递减数组int nArr3[5] = {8,7,6,5,4};PrintMessage(nArr3, 5);//有重复数字的数组int nArr4[5] = {7,4,8,4,8};PrintMessage(nArr4, 5);//只有两个数字的数字int nArr5[2] = {7,5};PrintMessage(nArr5, 2);int nArr6[1] = {4};PrintMessage(nArr6, 1);system("pause");return 0;}运行结果:
- 面试题29:数组中的逆序对
- 面试题36:数组中的逆序对
- 数组中的逆序对(面试题 36)
- 面试题36:数组中的逆序对
- 面试题36:数组中的逆序对
- 面试题36:数组中的逆序对
- 面试题36数组中的逆序对
- 面试题40:数组中的逆序对
- 面试题36:数组中的逆序对
- 面试题36:数组中的逆序对
- 面试题36:数组中的逆序对
- 面试题36:数组中的逆序对
- 面试题 36: 数组中的逆序对
- 面试题36:数组中的逆序对
- 面试题36. 数组中的逆序对
- 程序员面试题——数组中的逆序对
- 剑指offer面试题36:数组中的逆序对
- [剑指offer][面试题36]数组中的逆序对
- spring 3.0 应用springmvc 构造RESTful URL 详细讲解
- hdu4604 Deque
- js_跨域访问问题解决方法
- windows server 2012 AD 活动目录部署系列(六)部署额外域控制器
- MTU参数详解
- 面试题29:数组中的逆序对
- 飞思卡尔单片机DZ60---EEPROM读写
- 关于Android的字体
- 设备模型8之电源管理(二)(平台接口,详细分析mini2440平台的睡眠和唤醒)
- Linux下高性能网络编程中的几个TCP/IP选项
- uva 10763 - Foreign Exchange 水
- 常用排序算法完全版 快排优化 归并排序的非递归实现
- Android学习错误处理
- Android LOG机制的实现