【算法题】求数列中所有数字的小和之和问题
来源:互联网 发布:日本买什么划算 知乎 编辑:程序博客网 时间:2024/06/09 19:04
归并排序的应用问题
归并排序可参考上一篇博客。
归并排序另一应用:逆序对。
问题描述:
一个数列,其中一个数p,其左边所有比p小的数的和,是数p的小和。
求这个数列所有数的小和之和。
思路
利用归并排序的过程完成求小和问题。
已知归并过程如下:
1、首先划分划分划分,一直划分到不能划分,即每个组都只有一个数值。
2、然后合并,合并的过程就是每个二划分排序的过程。
3、在合并的时候,开辟一个辅助数组,其大小等于这两个合并数列的大小。
4、设置两个指针分别指向每个数列的首部,然后比较得到其中较小的值,并将这个值放入辅助数组中。然后取出小值的那个数列的指针可以继续向前走,与另一个数列的指针所指向的值继续比较。
5、这样比较完成后,如果两个数列中有个数列的数值有剩余,即其指针没有走到末尾,则将这个数列直接赋到辅助数组末尾即可。
6、然后将辅助数组中的值拷贝回原数组中刚才合并的那两个数列的位置上。
下面举例:
3 7 5 9合并:设置辅助数组:3 (5比3大,3放入数组中)3 5 (7比5大,5放入数组中)3 5 7 (9比7大,7放入数组中)3 5 7 9 (数列1结束,直接将数列2放入辅助数组末尾,即9放入数组中)完成一次合并排序。下一次,3 5 7 9 可以和 1 4 6 8进行合并排序。
在上面例子中,左边数列3与5比较时,它是5左边的数,且比5小,则3会出现在5的小和中。求已知5所在的数列是有序的,则9定比3大,3也会出现在9的小和中。所以在此次合并排序的过程中,3会参与2次小和的计算,可以记录下3*2的值。
而由于这是个递归的过程,每个数列都是由包含一个数值开始合并排序的,所以所有数都会遇到其右边比它大的数,所以这个过程既不会少算也不会多算。
体现在代码中,就是当左边数列中的数p比右边数列中的数q小时,则直接可以记录有x个左边数p相乘即可,有x个就是右边数列q及其之后有几个数。count += a[p1] < a[p2] ? (r - p2 + 1)*a[p1] : 0;
代码
#include <iostream>#include <vector>using namespace std;/*2017/11/12利用归并排序求小和*/#if 1int merge(vector<int>&a, int l, int mid, int r){ int count = 0; int p1 = l; int p2 = mid + 1; int i = 0; vector<int>help(r - l + 1); while (p1 <= mid && p2 <= r) { count += a[p1] < a[p2] ? (r - p2 + 1)*a[p1] : 0; help[i++] = a[p1] < a[p2] ? a[p1++] : a[p2++]; } while (p1 <= mid) help[i++] = a[p1++]; while (p2 <= r) help[i++] = a[p2++]; for (i = 0; i < help.size(); i++) a[l + i] = help[i]; return count;}int mergeSort(vector<int>&a, int l, int r){ if (l == r) return 0; int mid = l + (r - l) / 2; return mergeSort(a, l, mid) + mergeSort(a, mid + 1, r) + merge(a, l, mid, r);}int SmallSum(vector<int>a){ if (a.size() < 2) return 0; return mergeSort(a, 0, a.size() - 1);}void main(){ vector<int>a = { 7, 2, 14, 6, 14 }; cout << SmallSum(a) << endl; system("pause");}#else#endif
阅读全文
0 0
- 【算法题】求数列中所有数字的小和之和问题
- 迭代法求分数数列之和 小母牛繁殖问题
- 问题一百:求数列之和
- 【算法题】求有序数列中相邻数字之间的最大差值
- 递归函数求n和求数组所有元素之和的问题
- [算法]求数列最大连续数和的问题
- 求字符串中数字之和
- 求字符串中数字之和
- 练习:求string语句中所有的数字和
- 百度笔试算法题:算法题:给你一个自然数N,求[6,N]之内的所有素数中,两两之和为偶数的那些偶数。
- 算法题8 在给定数列中查找和为给定值的两个数字
- 求1-n中所有数的最大公约数之和
- 求数列的最大字段和 算法
- 算法题:给你一个自然数N,求[6,N]之内的所有素数中,两两之和为偶数的那些偶数。
- 算法题:给你一个自然数N,求[6, N]之内的所有素数中, 两两之和为偶数的那些偶数。
- 问题 B: 求各位数字之和
- 算法题-数列的前n项之和及扩展
- 【HDU 4217】【经典题 树状数组求前k大】 Data Structure?【n个数1-n,k次操作,每次取出第ki小的数。问所有取出数字之和。】
- oracle id 自增长
- SpringMVC返回XML和JSON
- eclipse下载及简单配置
- 1682亿!!阿里工程师如何喝着茶创造双11奇迹?
- 有相同键值的json合并为一个数组
- 【算法题】求数列中所有数字的小和之和问题
- C++设计模式实例讲解
- 使用PreparedStatement的setString方法会自动在数据库相应表项后面补空格解决办法
- Android笔记之版本更新
- c++ primer 笔记,第十章(泛型算法)
- 移动前端
- Effective Java 3 -- Singleton的优化实现
- 超全的深度剖析内存系列——3.虚拟内存(二)
- Java中JDK,JRE,JVM的区别