剑指offer面试题之求数组中逆序对的个数
来源:互联网 发布:青岛seo排名软件 编辑:程序博客网 时间:2024/06/05 06:49
1,问题:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
2,想法:
(1),暴力枚举法o(n2)
(2),利用归并的思想,先计算左半边的逆序对数,再计算右半边的逆序对数,再计算合并时的逆序对数,合并的过程中排序。方便上层递归计算。
3,在牛客网上的编码为:
class Solution {public: int merge(int* p, int low, int mid, int high) { int m = mid - low + 1; int n = high - mid; int* temp1 = new int[m]; int* temp2 = new int[n]; int i,j; int count = 0; int tempflag = 0;//临时标记值,用来记录当前以i为首的逆序对个数 for (i = 0; i < m; i++) { temp1[i] = p[i + low]; } for (j = 0; j < n; j++) { temp2[j] = p[j + mid + 1]; } int k = low; //整个算法的难点就在合并这里,看怎么计算count for (i = 0, j = 0; i < m && j < n;) { if (temp1[i] > temp2[j]) { count++; p[k] = temp2[j]; tempflag = count;//时刻标记着,记录以当前i为首的逆序对的个数 j++; k++; } else { p[k] = temp1[i]; i++; k++; //count = count + count;//这里不能是翻倍的增加,会放大 //例子就是6,5,4,3,2,1,应该增加的是以i-1为首的逆序对个数 //在决定是否加tempflag前,应该判断i值是否已经超出 //超出就不再加了,因为这时的i不存在,若加就多算了一次 //例子就是1,2,1,2,1 if (i < m) { count = count + tempflag; } } } if (i < m) { p[k] = temp1[i];//以这个i为首的逆序对已经求了,不能再算一次 k++; for (i = i + 1; i < m; i++)//现在以i为首的逆序对数就是tempflag个 { p[k] = temp1[i]; //count = count + count; count = count + tempflag; k++; } } else if (j < n) { for (j; j < n; j++) { p[k] = temp2[j]; k++; } } delete temp1; delete temp2; return count; } int Count(int *p, int low, int high) { if (p == NULL || low == high) { return 0; } int count = 0; if (low < high) { int mid = (low + high)/2; int leftcount = Count(p, low, mid); int rightcount = Count(p, mid + 1, high); int mergecount = merge(p, low, mid, high); count = leftcount + rightcount + mergecount; } return count; } int InversePairs(vector<int> data) { //O(n2),最笨方法 /*if (data.empty()) { return 0; } unsigned int i,j; int count = 0; for (i = 0; i < data.size(); i++) { for (j = i + 1; j < data.size(); j++) { if (data[i] > data[j]) { count++; } } } return count;*/ if (data.empty()) { return 0; } unsigned int i; int m = data.size(); int *temp = new int[m]; for (i = 0; i < m; i++) { temp[i] = data[i]; } return Count(temp, 0, m - 1); }};在利用合并的思想要注意的几点:
(1),怎么尽量少使用辅助空间
(2),在合并的过程中,计算逆序对,需要考虑全面,即将两个有序数组合A(在前)和B(在后)并为一个有序数组的过程中,每次A数组的指针i增加1时,先要考虑这个指针i是否已经超出限制条件,若没有,那以这个指针i所在位置值为首的逆序对,至少都有以i-1所在位置为首的逆序对个数那么多个。而我们需要做的就是记录以当前i所在位置值为首的逆序对的个数。以方便当i增加1时,把握count的变化。
1 0
- 剑指offer面试题之求数组中逆序对的个数
- 剑指offer 面试题36 数组逆序对个数
- 剑指offer面试题36 数组中逆序对个数,hulu面试题,要求写代码发过去
- 剑指offer之面试题36数组中的逆序对
- 剑指Offer之面试题36:数组中的逆序对
- 《剑指Offer》面试题:数组中的逆序对的总数
- 剑指offer之面试题36:数组中的逆序对-归并排序的应用
- 求数组中逆序对的个数
- 求数组中逆序对的个数
- 剑指OFFER_求数组中逆序对的个数
- 剑指offer面试题之求一个整数二进制中1的个数
- 剑指offer面试题36:数组中的逆序对
- [剑指offer][面试题36]数组中的逆序对
- 【剑指offer】面试题36:数组中的逆序对
- 剑指Offer:面试题36 数组中的逆序对
- 剑指offer 面试题36:数组中的逆序对
- 剑指offer 面试题36—数组中的逆序对
- 【剑指Offer学习】【面试题36:数组中的逆序对】
- CoreMotion 使用心得
- 微生物增殖
- 第四周项目一 求任意四个数的公约数
- 单链表的C++实现
- Spring Security 引用数据库管理用户权限-----login.jsp 提示"用户名或密码错误"
- 剑指offer面试题之求数组中逆序对的个数
- hibernate实现增删改查的各种方法
- 找素数
- Eclipse加入PHP插件并支持PHP自动提示
- 问题:XMLHttpRequest cannot load file~~Origin 'null' is therefore not allowed access
- Netty精粹之TCP粘包拆包问题
- IP之于游戏
- 集成学习
- STM32——流水灯