众数问题(递归、分治)
2017-11-18 22:01
309 查看
所谓众数,就是对于给定的含有N个元素的多重集合,每个元素在S中出现次数最多的成为该元素的重数,
多重集合S重的重数最大的元素成为众数。例如:S={1,2,2,2,3,5},则多重集S的众数是2,其重数为3。
现在你的任务是:对于给定的由m个自然数组成的多重集S,计算出S的众数及其重数。
解题思路:
(1)快速排序
(2)求中位数
(3)计算出中位数的最左端和最右端的位置,然后分割成2段数组
(4)中位数个数与左端个数比较,中<左 即最大众数可能存在左端,将左端再进行2段分割(递归)直到 中 > 左为止。 右端同理。。。
多重集合S重的重数最大的元素成为众数。例如:S={1,2,2,2,3,5},则多重集S的众数是2,其重数为3。
现在你的任务是:对于给定的由m个自然数组成的多重集S,计算出S的众数及其重数。
解题思路:
(1)快速排序
(2)求中位数
(3)计算出中位数的最左端和最右端的位置,然后分割成2段数组
(4)中位数个数与左端个数比较,中<左 即最大众数可能存在左端,将左端再进行2段分割(递归)直到 中 > 左为止。 右端同理。。。
#include<bits/stdc++.h> using namespace std; const int maxn = 1e2+5; int num , val,n; int a[maxn]; void find(int &l,int &r,int id) { l = id,r = id; while(a[l] == a[id] && l >= 1) --l; l++; while(a[r] == a[id] && r <= n) ++r; r--; return ; } void solve(int l,int r) { if(l > r) return ; int mid = l + r >> 1; int i,j; find(i,j,mid); if(j - i + 1 > num) { num = j - i + 1; val = a[mid]; } if(i - l > num) solve(l,i-1); if(r - j > num) solve(j+1,r); return ; } int main() { srand(0); //freopen("input.txt","r",stdin); //freopen("output.txt","w",stdout); while(cin >> n) { /*for(int i = 1;i <= n;++i) cin >> a[i];*/ for(int i = 1;i <= n;++i) a[i] = rand() % 10; sort(a+1,a+n+1); for(int i = 1;i <= n;++i) printf("%d%c",a[i],i == n ? '\n' : ' '); num = val = 0; solve(1,n); printf("%d %d\n",val,num); } return 0; }
相关文章推荐
- 递归与分治策略——集合划分问题,众数问题
- 众数问题-递归和分治
- 关于分治和递归的几点思考 有关全排序问题
- 众数问题(递归)
- 递归和分治思想的典型应用—汉诺塔问题
- 数组的众数问题分治法解法
- 使用递归-分治方法解决汉诺塔问题
- 数组的众数问题的分治解法
- 递归和分治思想解全排列问题
- 分治与递归——标准二维表问题
- 递归分治解决全排列问题
- 第二章 递归与分治策略(排列的字典序问题)
- 循环日程表 问题(递归分治)
- [分治,递归]棋盘覆盖问题
- 棋盘覆盖问题(递归分治)
- 汉诺塔问题(递归与分治)
- 分治与递归-棋盘覆盖问题
- 棋盘覆盖问题-递归分治
- [置顶] 递归与分治策略-2.9.2线性时间选择(取中位数的中位数基准)(第k小问题)
- 递归和分治思想4|八皇后问题 – 数据结构和算法34