标签:
采用分治法,以中间为界限, 先计算围绕中间这个数字的众数情况,然后左右分开递归计算结果,取最值即可。
左右递归计算的时候要先做判断,假如左边或是右边的个数都比已求的重数小,就没必要计算了,即使左边或是右边全部都是一样的,那么他的重数也是小于已求的,所以没必要进行运算,这一周在加深分治算法的学习,这题着实花了我不少时间。
具体代码:
// 用分治法求众数 #include <iostream> #include <cstdio> using namespace std; // 本程序的关键, 以中间的数字为界限, 确定左右起始和终止界限 void split(int s[], int n, int &l, int &r) { int mid = n/2; for(l=0; l<n; ++l) { if (s[l] == s[mid]) break; } for(r=l+1; r<n; ++r) { if (s[r] != s[mid]) break; } } // num 众数, maxCnt 重数 void getMaxCnt(int &mid, int &maxCnt, int s[], int n) { int l, r; split(s, n, l, r); // 进行切割,这个函数是本程序的关键 int num = n/2; int cnt = r-l; // update if (cnt > maxCnt) { maxCnt = cnt; mid = s[num]; } // l 表示左边的个数,左边的个数必须大于 maxCnt 才有必要搜寻 if (l+1 > maxCnt) { getMaxCnt(mid, maxCnt, s, l+1); } // 右边搜寻, 右边数组的起始地址要变更 if (n-r > maxCnt) { getMaxCnt(mid, maxCnt, s+r, n-r); } } int main(void) { int s[] = {1, 2, 2, 2, 3, 3, 5, 6, 6, 6, 6}; int n = sizeof(s)/sizeof(s[0]); int maxCnt = 0; int num = 0; getMaxCnt(num, maxCnt, s, n); printf("%d %d\n", num, maxCnt); return 0; }
大概思路图:
版权声明:本文为博主原创文章,未经博主允许不得转载。 http://blog.csdn.net/core__code
标签:
原文地址:http://blog.csdn.net/core__code/article/details/47385045