[C/C++] 用线性时间选择来找无序数组的中位数

分治法——线性时间选择问题 问题 线性时间选择问题:给定线性序集中n个元素和一个整数k(k>=1而且k<=n),要求在线性时间内找出这n个元素中第k小的元素。 方法 随机快速排序 #include <stdio.h> #include <stdlib.h> int main() { int a[100],n,k,i,t,j;//定义变量 scanf("%d %d",&n,&k);//输入数组大小n,整数k for(i=0;i<n;i++)//循 阅读详情

有一道题大概是这样的:有n条水平的线,知道线的纵坐标,选择一条线,使得这条线到所有线的距离之和最小。

根据数学知识,我们知道,如果线是奇数条的话,那么中间那条(纵坐标的中位数)即可,如果是偶数条的话,那么中间那2条区间内的都可以,而如果要线的纵坐标尽可能小,那么就取中间两条纵坐标较小的那条即可。

那么在线数量为偶数的时候,这并不是传统的求中位数问题,而线数量为奇数的时候,则变成传统的中位数问题。

求中位数的方法可以先排序然后直接取中间的一条即可,但是对于大数据量来说,排序不可行。利用线性时间选择可以再O(n)下找到中位数。


线性时间选择将数组分成3部分,一部分是基准(1个数),其他两部分是大于这个基准的数组和小于基准的这个数组,对于长度为n的数组来说,我们目的是找到第k=(1+n)/2个数,那么就可以根据k和基准的关系来判断第二次是在小于基准的数组里查找还是在大于基准里的数组查找。程序如下:

#include<iostream>
using namespace std;
#define MAX 100001
int main()
{
	int a[MAX];
	int *p=a;
	int x,y,t1,n=0;
	char t2;
	cin>>n;
	for(int i=0;i<n;i++) cin>>a[i];
	int* small=new int[n]; //小于中位数的集合
	int* big=new int[n]; //大于中位数的集合
	int equal; //等于中位数的那个数,也就是基准
	int k=(1+n)/2;  //处于数组最中间索引的元素

	while(1)
	{
		int x=p[rand()%n]; //随机选取一个数做基准
		int n_s=0,n_b=0;
		for(int i=0;i<n;i++) //将n个数划分成3组:小的集合,基准,大的集合
		{
			if(p[i]>x) big[n_b++]=p[i];
			else if(p[i]==x) equal=x;
			else small[n_s++]=p[i];
		}
		//划分
		if(k<=n_s){ //如果小的集合元素数量多于k,说明中位数处于小集合中
			p=small;
			n=n_s;
			//k不变
		}
		else if(k==n_s+1){ //k正好是中间的基准,找到中位数
			break;
		}
		else{ //小的集合元素数量小于k,说明中位数位于大的集合中
			p=big;
			n=n_b;
			k=k-1-n_s; //此时,我们需要找的原来的第k个元素变成了大集合中的第k-n_s-1个元素
		}
	}
	cout<<equal<<endl;
	system("pause");
	return 0;
}

算法题04:分治法:求第K小元素(线性时间选择算法) 求第k小元素 题目内容: 给定一个线性序列集,要求使用分治法求出其中指定的第 KKK 小的数的值和位置,如给定 nnn 个元素和一个整数 iii,1≤i≤n1≤i≤n1≤i≤n,输出这 nnn 个元素中第 iii 小元素的值及其位置。 一、问题分析(模型、算法设计和正确性证明等) 解决第K小问题有如下几种方法 ①将n个数排序(比如快速排序或归并排序),选取排序后的第k个数,时间复杂度为O(nlog... 阅读详情

相关推荐

分治策略实战:线性时间选择算法 75 元素阈值与中位数分组策略详解

本文深入解析线性时间选择算法(BFPRT算法)的核心设计,重点探讨75元素阈值与5元素中位数分组策略的数学原理与工程优化。通过分治策略实现最坏情况下O(n)时间复杂度,详细分析阈值选择、分组大小对算法性能的影响,并提供实际代码示例与性能对比数据,帮助开发者掌握这一高效选择算法的实现精髓。

weixin_42665725的博客 310

线性时间查找中位数算法

一般来说,中位数的查找算法都是基于先排序,后找中间位置的数字的算法,但是因为线性时间排序所收到的限制比较大,而如果使用基于比较的排序,时间复杂度将至少为O(nlogn),如何以线性时间完成中位数或者数组中第N大元素的查找呢?

Go With Heart的专栏 9438

深信服C/C++面试题目总结

内容收集自网络 1. 链表和数组的相同点和不同点 特点 优点 缺点 数组 存储区域连续需要预先分配空间,可能造成空间浪费或者不利于扩展插入/删除效率低随机读取效率高 随机访问性强查找速度快 插入和删除效率低可能浪费内存内存空间要求高,必须有足够的连续内存空间数组大小固定,不能动态拓展 链表 存储区域不要求连续,每个数据都保存了下一个数据的地址(如果有)数据的增加/删除容易,易...

Secur17y的博客 6704

线性时间的中位数查找算法

原帖链接 一、以期望线性时间做选择 一般来说,中位数的查找算法都是基于先排序,后找中间位置的数字的算法,但是因为线性时间排序所收到的限制比较大,而如果使用基于比较的排序,时间复杂度将至少为O(nlogn),如何以线性时间完成中位数或者数组中第N大元素的查找呢? 快速排序算法在每一次局部递归后都保证某个元素左侧的元素都比他小,右侧的元素都比她大,因此,可以利用这个思路快

jelly_can的专栏 2850

【EduCoder答案】C/C++实训答案

简介 其他各类实训答案的目录见这里 答案查询的入口见这里 答案获取的方法简介见这里 并不是所有的关卡都有答案,有些只有部分关卡有,因为金币不太够… C/C++相关实训答案 C&C++基本输入输出 >>>链接 第1关: 重要的事情说三遍 解题代码 // 包含标准输入输出函数库 #include <stdio.h> // 定义main函数 int main() { // 请在下面编写将字符输出三遍的程序代码 /********** Begin *****

weixin_44505587的博客 5530

LeetCode-4.寻找两个正序数组的中位数 C++实现

给定两个大小分别为m和n的正序(从小到大)数组nums1和nums2。请你找出并返回这两个正序数组的。算法的时间复杂度应该为。2.00000合并数组 = [1,2,3] ,中位数 22.50000合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5。

2401_86645122的博客 2061

查找无序数组的中位数

[C++] 查找无序数组的中位数(利用大小顶堆实现)

a1651950431的博客 1122

线性时间选择算法实验:完整数据、代码、说明及测试

选择问题是指在一组数据中找到第k小(或第k大)的元素,其中k是一个非负整数且小于数据的总数。线性时间选择算法的主要目标是高效地解决这个问题,特别是在数据量较大的情况下。选择问题与排序不同,因为排序的目标是将所有元素按照一定的顺序排列,而选择问题仅需找到特定位置的元素。该算法在数据库查询、统计分析以及一些优化问题中有着广泛的应用。分治策略(Divide and Conquer)是计算机科学中一种重要的算法设计范式。

weixin_30248619的博客 896

【C/C++ 力扣leetcode】4道简单题

4道简单C/C++ leetcode题目,让你C/C++编码能力起飞!!!

m0_62599305的博客 1661

线性时间选择算法的C++实现

线性时间选择算法的C++实现 g++下编译通过

tuts4you-lena151-Crackme-tutorial06

一、前言      本次研究的是lena151-Crackme-tutorial06,也是一个应用程序,但因为平台迭代的关系,程序不能正常运行,只能完成部分破解。 (一)·本次我们要破解的目标是个应用程序,如下图 (二)、使用工具:x32dbg 二、过程 这个程序的破解的方法很多,首先最简单的一种不外乎就是搜索字符串,我就按照这个思路来完成。 (一)查找字符串&lt;Unregis...

h123120的专栏 520

算法:线性时间选择(C/C++)

Description 给定线性序集中n个元素和一个整数k,n<=2000000,1<=k<=n,要求找出这n个元素中第k小的数。 Input 第一行有两个正整数n,k. 接下来是n个整数(0<=ai<=1e9)。 Output 输出第k小的数 Sample Input 6 3 1 3 5 2 4 6 Sample Output 3 利用快速排序可以找出第k小的,加上随机函数改进一下: AC代码: #include <cstdio> #include <c

yanhua_tj的博客 8478

Fiddler Everywhere保姆级教程:10分钟搞定手机HTTPS抓包(附证书配置避坑指南)

本文提供Fiddler Everywhere移动端HTTPS抓包的保姆级教程,涵盖环境配置、代理设置、证书安装及常见问题排查。重点解析如何正确安装并信任Fiddler根证书以解密HTTPS流量,帮助开发者快速搭建抓包环境,高效分析应用网络行为,提升调试效率。

git9versioner的博客 705

(C/C++)给定一个带权无序数组,线性复杂度求出其带权中位数(select分治算法)

给定一个未排序的数组(x1, x2, … ,xn),其中每个元素关联一个权值:(w1, w2, … ,wn),且 。请设计一个线性时间的算法,在该数组中查找其带权中位数xk,满足: 思路 基于寻找无序数组第k小个数的select算法,以rand()选出的pivot将数组分为三个部分,并进行前后两部分权值总和的判断。 若leftWeight <=0.5 && rightW...

周周的奇妙代码之旅 1575

NVIDIA Tao Toolkit环境配置踩坑

请搭配食用该文章为 Tao 安装中可能出现的问题进行解答,如果存在本文章中没出现的问题,欢迎提问,由我复现后更新文章。由于大部分云服务器厂商不能支持 docker,因此我使用的环境为2023年5月27日在平台租的 3080 旧版环境进行实验。

qq_36630208的博客 772

华为eNSP Pro实战:NE/CE设备SSH远程配置避坑指南

本文针对华为eNSP Pro用户在模拟多台NE路由器或CE交换机时遇到的浏览器卡顿问题,提供了详细的SSH远程配置避坑指南。通过对比浏览器与SSH客户端的资源占用和操作体验,文章详细阐述了为NE和CE设备配置SSH服务的关键步骤、命令差异及常见错误排查方法,旨在帮助用户提升实验效率,实现稳定高效的远程管理。

weixin_29196891的博客 224

算法设计与分析之线性时间选择(C++)

算法设计与分析之线性时间选择

Blank 2604

【vue看板】

大屏看板提示:以下是本篇文章正文内容,下面案例可供参考提示:这里对文章进行总结:代码量较多,看板中的。

weixin_46223284的博客 2772

【scau算法分析设计|整理】线性时间选择(找第k小/大数)

k:找第k小的元素 一、一般线性时间选择问题 (1) 排序法 通常算法:排序;找第k小的数(但是会冗余) (2) 堆+部分排序 意思:不构成完全堆,指利用其中一部分。 建最小堆,然后弹堆顶k次。 优点:比数组好,经得起反复找。 缺点:空间消耗大。 时间复杂度:O(n+k*logn)。【当k很小,就约等于线性效率】 (3) 堆(O(nlogk))【好方法—— 把前k小的元素放入堆(最大堆)中,则堆顶为第k小的数。 优点:堆的空间很小。 最详细的堆排序-...

weixin_51159944的博客 445

小程序 video 控制器外观调整_Kessil 360X Tuna Sun无线控制器使用分享

之前分享了Kessil 360X Tuna Sun开箱记录,时间关系,没来得及使用WiFi Dongle无线控制器。昨晚抽空实操了一下,做个操作记录,希望对大家有参考Kessil无线模块操作指南官方视频英文教程配中文字幕,非常详尽语速较快,重点位置可以暂停操作点击边框调出视频工具条1、拆包取控制器,保存二维码Kessil WiFi Dongle包装打开包装就能看到Kessil无线控制模...

weixin_39759060的博客 4734

DPO(Direct Preference Optimization)实战全流程指南

《DPO实战全流程指南》摘要 本文提供了端到端的DPO(直接偏好优化)实战方案,包含数据准备、模型训练、评估部署全流程。核心内容包括: 数据构建:推荐UltraFeedback等高质量数据集,提供数据预处理代码 训练配置:基于HuggingFace TRL库的DPO实现,详解beta值等关键参数调优 工业优化:显存节省技巧(LoRA、梯度检查点)、领域自适应方法和在线学习架构 效果评估:量化对比显示DPO可降低86%有害回复率,提升24%用户满意度 常见问题:针对灾难性遗忘、过度安全化等问题给出解决方案 附

技术引领业务创新 1468

线性时间选择(C++):求第k小的数

方法一: 思想:首先对整个数组进行划分,利用Partition函数,以数组中某个数为基准(这里以首项为标准)将数组划分为两部分——左边部分的所有数都小于基准,右边部分都大于基准,并返回基准数的下标值。 然后,如果要找到第k小个数,就将k的大小与数组左半边元素的个数(若为j,包括基准)进行比较,如果k小于j,则对左边部分进行递归,找第k小个数;若k大于j,...

帅聪锅锅的博客 6697

【AI编程】2025年16款主流AI编程工具全维度测评及选型指南

2025年16款主流AI编程工具全维度测评及选型指南

funfan的博客 1万+

c语言 整型数组排序库函数_使用C ++标准库函数在线性时间中查找未排序数组的中位数...

c语言 整型数组排序库函数Prerequisite: std::nth_element() in C++ 先决条件: C ++中的std :: nth_element() Problem statement: 问题陈述: Find the median of an unsorted array. 查找未排序数组的中位数。 What is median? 什么是中位数? A medi...

cumubi7552的博客 711

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

BAT面试题 - 找一个无序实数数组中的最大差值

BAT面试题——找一个无序实数数组中的最大差值 (基于桶排序思想的方法)

艾斯 6771

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

C/C++头文件汇总

C/C++头文件汇总

阿玥的小博客 2万+

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

上一篇: [C/C++] 电缆分割问题(二分查找的应用)
下一篇: [C/C++] 回溯法解0-1背包问题
PerryXu_BIT
博客等级 码龄12年 5粉丝 18原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值