为了解决这道题,我们选用了c++中的vector作为数据结构,因为vector的增加,删除操作较为简单。

要解决该问题我们需要几个相关函数作为支持。

vector<int> find_k_near_mid(vector<int>& list, int k)
//主要的求解函数,返回值为一个vector数组。
int select(vector<int> list,int tt)
//求解输入的list中的有序时的第tt个数(从0开始计算)的值
sort(vector<int> &list)
//插入排序算法
int partition(vector<int> &list, int x)
//以x为主元对list进行划分
int partition1(vector<vector<int>> &list, int x)
//功能与上一个函数一致,只是输入参数不同

select()函数:该函数可以返回按序排列的第tt个数的值,我们也可以用它来求解中位数。

它是通过划分数组,之后递归调用的方式执行,时间复杂度为O(n),书上有更为具体的描述.

​int select(vector<int> list,int tt){if(list.size() == 1){return list[0];}vector<vector<int>> div; for(int i = 0; i <= list.size()/5; i++){vector<int> temp;for(int j = 0; j < 5; j++){if(i * 5 + j == list.size()){break;}temp.push_back(list[i * 5 + j]); }if(temp.size() != 0){sort(temp);//用冒泡排序的方法对这5个数排序div.push_back(temp);                }}//建立二维vector,5个一组存储list的值vector<int> mid_temp(div.size());for(int i = 0; i < div.size(); i++){mid_temp[i] = div[i][(div[i].size()-1)/2];}//建立存储中位数的vectorint mid_mid_temp;mid_mid_temp = select(mid_temp, (mid_temp.size()-1)/2);//求中位数数组的中位数int position_mid_mid_temp = partition(list, mid_mid_temp);//求出中位数数组的中位数在list中的位置,并对中位数数组做划分,k之前是小于mid_mid_temp的数,之后是大于该值的数。int k = position_mid_mid_temp;vector<int> low(list.begin(), list.begin() + k);vector<int> high(list.begin() + k + 1, list.end());//用k对数组进行划分if(tt == k){return mid_mid_temp;}else if(tt < k){return select(low, tt);}else {return select(high, tt - k - 1);}          }​

sort()函数:插入排序,不需要过多介绍。

    void sort(vector<int> &list){int temp;for(int i = 0; i < list.size(); i++){for(int j = i; j < list.size(); j++){if(list[i] > list[j]){temp = list[i];list[i] = list[j];list[j] = temp;}}}}

partition()函数:以传入的x为主元,对数组进行划分,并且返回x在划分好的数组中的位置。

    int partition(vector<int> &list, int x) {int i = -1,temp;for(int j = 0; j < list.size(); j++){if(list[j] <= x){i++;temp = list[j];list[j] = list[i];list[i] = temp;}}return i;}int partition1(vector<vector<int>> &list, int x) {int i = -1;vector<int> temp;for(int j = 0; j < list.size(); j++){if(list[j][1] <= x){i++;temp = list[j];list[j] = list[i];list[i] = temp;}}return i;}  

find_k_near_mid()函数:

首先,调用select()函数求出中值,之后建立一个二维vector,每一维有两个参数,第一个为list中的数减去mid的符号,第二个为这个值的绝对值。这个绝对值也存储在一个名为temp的容器中。

我们调用select()函数,求出temp中有序排列时的第k(从1开始计数)个值。之后通过这个值调用partition1()函数对二维容器进行划分。

在数组划分好后,我们用前k个值的绝对值乘以符号位加上中位数即为需要的值。

    vector<int> find_k_near_mid(vector<int>& list, int k) {int mid = select(list, (list.size()-1)/2);vector<vector<int>> b(list.size());vector<int> temp;int temp_num;for(int i=0; i<list.size(); i++){temp_num = list[i] - mid;if(temp_num < 0){b[i].push_back(-1);b[i].push_back(abs(temp_num));temp.push_back(abs(temp_num));}else{b[i].push_back(1);b[i].push_back(temp_num);temp.push_back(temp_num);}}int x = select(temp, k-1);partition1(b, x);vector<int> result;for(int i=0; i<k; i++){result.push_back(b[i][0]*b[i][1] + mid);}return result;}

完整代码(含测试代码):

#include<vector>
#include <iostream>
#include <stdlib.h>using namespace std; class Solution {
public:vector<int> find_k_near_mid(vector<int>& list, int k) {int mid = select(list, (list.size()-1)/2);vector<vector<int>> b(list.size());vector<int> temp;int temp_num;for(int i=0; i<list.size(); i++){temp_num = list[i] - mid;if(temp_num < 0){b[i].push_back(-1);b[i].push_back(abs(temp_num));temp.push_back(abs(temp_num));}else{b[i].push_back(1);b[i].push_back(temp_num);temp.push_back(temp_num);}}int x = select(temp, k-1);partition1(b, x);vector<int> result;for(int i=0; i<k; i++){result.push_back(b[i][0]*b[i][1] + mid);}return result;}int select(vector<int> list,int tt){if(list.size() == 1){return list[0];}vector<vector<int>> div; for(int i = 0; i <= list.size()/5; i++){vector<int> temp;for(int j = 0; j < 5; j++){if(i * 5 + j == list.size()){break;}temp.push_back(list[i * 5 + j]); }if(temp.size() != 0){sort(temp);div.push_back(temp);                }}vector<int> mid_temp(div.size());for(int i = 0; i < div.size(); i++){mid_temp[i] = div[i][(div[i].size()-1)/2];}int mid_mid_temp;mid_mid_temp = select(mid_temp, (mid_temp.size()-1)/2);//zhuyi  tt dezhi int position_mid_mid_temp = partition(list, mid_mid_temp);int k = position_mid_mid_temp;vector<int> low(list.begin(), list.begin() + k);vector<int> high(list.begin() + k + 1, list.end());if(tt == k){return mid_mid_temp;}else if(tt < k){return select(low, tt);}else {return select(high, tt - k - 1);}          }void sort(vector<int> &list){int temp;for(int i = 0; i < list.size(); i++){for(int j = i; j < list.size(); j++){if(list[i] > list[j]){temp = list[i];list[i] = list[j];list[j] = temp;}}}}int partition(vector<int> &list, int x) {int i = -1,temp;for(int j = 0; j < list.size(); j++){if(list[j] <= x){i++;temp = list[j];list[j] = list[i];list[i] = temp;}}return i;}int partition1(vector<vector<int>> &list, int x) {int i = -1;vector<int> temp;for(int j = 0; j < list.size(); j++){if(list[j][1] <= x){i++;temp = list[j];list[j] = list[i];list[i] = temp;}}return i;}
};
int main(){Solution A;int a[9]={1,2,3,4,5,6,7,8,9};vector<int> num1(a,a+9);int i = A.select(num1,4);cout << i << endl; vector<int> a1;a1=A.find_k_near_mid(num1,3);
}

新人博主,点个赞再走吧。

算法导论 9.3-7 设计一个O(n)时间的算法,对于一个给定的包含n个互异元素的集合S和一个正整数k≤n,该算法能够确定S中最接近中位数的k个元素。相关推荐

  1. 确定S中最接近中位数的k个元素(算法导论第三版9.3-7)

    确定S中最接近中位数的k个元素 (算法导论第三版9.3-7题) 时间复杂度O(n) vector<int> k_elements_closest_to_median(int *array, ...

  2. 【算法导论】学习笔记——第9章 中位数和顺序统计量

    在一个由n个元素组成的集合中,第i个顺序统计量(order statistic)是该集合中第i小的元素.用非形式化的描述来说,一个中位数(median)使它所属集合的"中点元素". ...

  3. 算法导论2-9章补充几道题

    本篇博文意在对前几章中遗漏的,本人觉得有意思的习题当独拿出来练练手. 1.习题2-4,求逆序对,时间复杂度要求Θ(nlgn) 定义:对于一个有n个不同的数组A, 当i<j时,存在A[i]> ...

  4. 2020美赛F奖论文(四):模拟退火算法驱动的结构策略设计

    上接:2020美赛F奖论文(三):足球团队指标和基于机器学习的球队表现预测 全文: 2020美赛F奖论文(一):摘要.绪论和模型准备 2020美赛F奖论文(二):传球网络模型(PNM)的建立和影响因子 ...

  5. 算法导论读书笔记(19)

    http://www.cnblogs.com/sungoshawk/p/3802553.html 算法导论读书笔记(19) 目录 最优二叉搜索树 步骤1:一棵最优二叉查找树的结构 步骤2:一个递归解 ...

  6. java毕业设计——基于java+MMAS的蚁群算法路由选择可视化动态模拟设计与实现(毕业论文+程序源码)——蚁群算法路由选择可视化动态模拟

    基于java+MMAS的蚁群算法路由选择可视化动态模拟设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+MMAS的蚁群算法路由选择可视化动态模拟设计与实现,文章末尾附有本毕业设计的 ...

  7. 算法导论笔记:32字符串匹配算法

    在编辑文本程序中,经常需要在文本中找到某个模式的所有出现位置.典型的情况是:在一个文本文件中,搜索用户输入的关键字.解决这种问题的算法叫做字符串匹配算法.字符串匹配算法的形式化定义如下:假设文本是长度 ...

  8. 《算法导论》——矩阵乘法的Strassen算法

    前言: 很多朋友看到我写的<算法导论>系列,可能会觉得云里雾里,不知所云.这里我再次说明,本系列博文时配合<算法导论>一书,给出该书涉及的算法的c++实现.请结合<算法导 ...

  9. python中值_Python中值,python,中位数

    有⼀个⽆序的整数序列(⽆重复项,⻓度为奇数),请⽤你认为最优的⽅法求序列的中位数.例如给 定数组 1.5.2.9.8.0.6,中位数是 5.要求算法的时间复杂度需要⼩于 O(n2),不能使⽤内置排 序 ...

  10. 树的直径 证明 算法导论

    树的直径的定义: 树中任意两点距离的最大值 树的直径的求法: 从树的任意一点y,通过BFS到达终点x:则x必为直径的一个端点.再从x通过BFS到达终点z.z必为直径的另一个端点.则从x经过BFS到z的 ...

最新文章

  1. Python——字符串大小写转化
  2. 军营中重重打击之后,我变了一个人(下)--我成为程序员所经历的(四)
  3. Hspice2008安装步骤
  4. linux安装weblogic9,linux_weblogic9_安装说明.doc
  5. nginx 配置php版本号,隐藏Apache、nginx和PHP的版本号的配置方法
  6. 深入理解java虚拟机 (二) 第二版
  7. 云盘运用了计算机技术,360云盘咋找出来
  8. 高性能可扩展mysql-数据库设计规范
  9. (35)Gulp 构建任务组合
  10. 在线邮箱地址提取工具
  11. 数学归纳法证明时间复杂度
  12. html5新增的一个input属性
  13. pythonATM,购物车项目实战3-视图函数
  14. IT草根的江湖之路之七: 挑战,刚刚开始
  15. 旧金山散记(一):第一次在美国打车
  16. 万能解压器安卓版_全能压缩软件下载
  17. 信息与计算机课件,第一章 信息技术与计算机ppt课件.ppt
  18. JSON字符串生成在线生成POJO工具类
  19. pg_repack安装及使用
  20. 数据预处理之白化(Whitening transformation)

热门文章

  1. Python随记(27)bs4爬取豆瓣250
  2. blendshape变形器详细解释
  3. 注意力模型(Attention Model)理解和实现
  4. 基于auto.js的安卓抢购软件---可实现毫秒级
  5. 怎样用计算机表白我爱你,微信表白的新套路,用隐藏性代码说我爱你,成功率99%...
  6. 徐思201771010132《面向对象程序设计(java)》第三周学习总结
  7. vue 微信支付的坑_微信支付踩坑
  8. linux mint运行速度,Linux Mint 19 Tara Cinnamon启动应用速度将会更快
  9. makefile中的隐含规则
  10. 前端实习周记07(毕业论文开题了。。。欧耶。。。欧耶。。。耶。。。)