算法设计与分析——递归与分治策略——线性时间选择

顾名思义:这篇文章讲解的就是如果用线性时间算法来作出元素选择问题。
问题描述:给定线性序集中n个元素和一个整数k,1<=k<=n.要求找出这n个元素中第k小的元素,即如果将这个n个元素依其线性序排列时,排在第k个位置的元素就是要找的元素,当k== 1时,要找的就是最小的元素;当k==n,就是最大的元素;当k=(n+1)/2,称为中位数。

问题分析:
在某些特殊的情况下,我们可以实现线性时间选择,对于找最大最小的元素O(n)内可以实现;当k<=n/logn,通过堆排序算法可以在O(n+klogn)=O(n)内实现;当k>=n-n/logn时也一样。
下面是给出的一般的选择问题,从渐近阶的意义上看,这个也可以在O(n)时间内完成。
下面的算法实现参考了《计算机算法与分析》和一些博客,是对其的一个整理。

方法一:
算法描述:用一个随机的序列中的数作为枢纽,用快速排序算法,进行一次快排,然后将枢纽值和k值进行比较,以此来确定k值,我并没有做任何的对比所以并不是清楚这种算法的效率有多少,但是搜到的结果表明,这种算法的最坏时间复杂度是O(n^2),相对与另一种是不太理想的。

解法:

1.首先大家都会想到的解法是排序,之后找出第k个元素,但是排序的时间复杂度不符合要求,或者需要额外的空间。

2.利用快排的思想,以枢纽(随机得到)为界,将数组分为2部分,一部分小于等于这个枢纽值,一部分大于这个枢纽值,与快排不同的是,我们只处理一部分,另一部分舍弃。

#include<bits/stdc++.h>
using namespace std;int partition(vector<int> &vec,int left,int right)
{int i=left;int j=right;int temp=vec[left];while(i<j){while(vec[j]>=temp&&i<j)//处理i,j的先后顺序不能改变 {j--;}while(vec[i]<=temp&&i<j){i++;}swap(vec[i],vec[j]);}vec[left]=vec[j];vec[j]=temp;return j;
}
int  QuickSort(vector<int> &vec,int left,int right,int k)
{if(left==right)return vec[left];int mid=partition(vec,left,right);int j=mid-left+1;if(k<=j)return QuickSort(vec,left,mid,k);elsereturn QuickSort(vec,mid+1,right,k-j);}
void print(int x)
{cout<<x<<" ";
}int main()
{vector<int> vec={1,2,3,6,5,4,7,8,9};for_each(vec.begin(),vec.end(),print);cout<<endl;int k;cout<<"请输入K(要求找出这n个元素中第k小的元素):" ;cin>>k;int count=vec.size()-1;cout<<QuickSort(vec,0,count,k)<<endl;QuickSort(vec,0,count,k);for(auto a:vec){cout<<a<<" ";}cout<<endl;} 

在这里插入图片描述
方法二:

这里我们就利用中位数来进行线性时间的选择算法!

中位数就是指将数据按大小顺序排列起来,形成一个数列,居于数列中间位置的那个数据就是中位数。

算法思路
(1)将输入的n个数划分成 ⌈n5⌉⌈n5⌉ 个组,当然最后一组的数目可能是小于5的!
(2)用任意的排序方法对他们进行排序,并取出一共 ⌈n5⌉⌈n5⌉ 个中位数。
(3)找出该 ⌈n5⌉⌈n5⌉ 个中位数中的中位数。(如果 ⌈n5⌉⌈n5⌉ 是偶数则取相对大的那个数)
(4)将全部的数划分为两个部分,小于基准的在左边,大于等于基准的放右边。

我们用小圆点表示元素,得到如下图:

在这里插入图片描述

说明:
图中中间白色圈表示各组数据的中位数,最中间灰色表示中位数的中位数! 箭头是从较小的数指向较大的数!

故我们可以使用该数作为划分的基准(比上一个随机基准的方法会好很多)!
在这里插入图片描述

图中
在这里插入图片描述

当n≥75时,3A1大于等于 14n14n。所以按此基准划分所得的左右2个子数组的长度都至少缩短 1414。

#include<bits/stdc++.h>
using namespace std;int partition(vector<int> &vec,int left,int right,int k)
{int i=left;int j=right;int temp=vec[k];while(i<j){while(vec[j]>=temp&&i<j)//处理i,j的先后顺序不能改变 {j--;}while(vec[i]<=temp&&i<j){i++;}swap(vec[i],vec[j]);}vec[k]=vec[j];vec[j]=temp;return j;
}void print(int x)
{cout<<x<<" ";
}int  Select(vector<int> &vec,int left,int right,int k)
{if(right-left<75){return vec[left+k-1];}for(int i=0;i<=(right-left-4)/5;i++){}int x=Select(vec,left,left+(right-left-4)/5,(right-left-4)/10);int i=partition(vec,left,right,x);int j=i-left+1;if(k<=j)return Select(vec,left,i,k);elsereturn Select(vec,i+1,right,k-j);}int main()
{vector<int> vec={1,2,3,6,5,4,7,8,9};for_each(vec.begin(),vec.end(),print);cout<<endl;int k;cout<<"请输入K(要求找出这n个元素中第k小的元素):" ;cin>>k;int count=vec.size()-1;cout<<Select(vec,0,count,k)<<endl;Select(vec,0,count,k);for(auto a:vec){cout<<a<<" ";}cout<<endl;} 

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/306644.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git push被拒绝_规范git项目提交并自动生成项目commit log

commit message 是开发的日常操作, 好的 log 不仅有助于他人 review, 还可以有效的输出 CHANGELOG, 对项目的管理实际至关重要, 但是在平时工作时&#xff0c;只依赖大致的开发规范和自觉&#xff0c;很难形成一种普遍约束。而通过本文&#xff0c;对项目进行一些基础配置&…

算法设计与分析——递归与分治策略——全排列

算法设计与分析——递归与分治策略——全排列 全排列问题的解决是通过分治与递归思想来解决的 首先判断是否递归到了最后一位&#xff0c;如果递归到了最后一位&#xff0c;则输出他当前的全排列序列。 如果没有到达最后一位&#xff0c;则循环的交换该第K个元素与其后面的所有…

asp.net core 集成 prometheus

asp.net core 集成 prometheusIntroPrometheus 是一个开源的现代化&#xff0c;云原生的系统监控框架&#xff0c;并且可以轻松的集成 PushGateway, AlertManager等组件来丰富它的功能。对于 k8s 下部署的系统来说使用 Prometheus 来做系统监控会是一个比较不错的选择&#xff…

vba 不等于_EXCEL中VBA基础语句(1)

萌二笔记分类目录及书单一、If-Then语句 说明&#xff1a;条件判断&#xff0c;如果......那么......例1&#xff1a;A2单元格的成绩大于等于60&#xff0c;则弹出对话框提示“及格”。Sub 判断成绩()If Range("A2") > 60 Then MsgBox "及格"End Sub操作…

leetcode——242. 有效的字母异位词

问题描述&#xff1a; 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 示例 1: 输入: s “anagram”, t “nagaram” 输出: true 示例 2: 输入: s “rat”, t “car” 输出: false 说明: 你可以假设字符串只包含小写字母。 进阶: 如…

.NET5发布了,腾讯招聘点名要求精通MySQL,而不是SQLServer!

.NET5正式发布&#xff0c;社区一片欢腾&#xff0c;.NET相关技术栈也会迎来大变革&#xff0c;而大厂的招聘要求可谓是技术风向标&#xff01;紧盯腾讯网易顺丰等大厂的招聘&#xff0c;会发现都在明确要求。MySQL&#xff0c;而不是SQL Server了。究其根本&#xff0c;还是跨…

C# WPF:把文件给我拖进来!!!

❝首发公众号&#xff1a;Dotnet9作者&#xff1a;沙漠之尽头的狼日期&#xff1a;202-11-27一、本文开始之前上传文件时&#xff0c;一般是提供一个上传按钮&#xff0c;点击上传&#xff0c;弹出文件&#xff08;或者目录选择对话框&#xff09;&#xff0c;选择文件&#xf…

github设置中文_【Github】100+ Chinese Word Vectors 上百种预训练中文词向量

(给机器学习算法与Python学习加星标&#xff0c;提升AI技能) 该项目提供了不同表征(密集和稀疏)上下文特征(单词&#xff0c;ngram&#xff0c;字符等)和语料库训练的中文单词向量。开发者可以轻松获得具有不同属性的预先训练的向量&#xff0c;并将它们用于下游任务。此外&…

服务器重新部署踩坑记

服务器重新部署踩坑记Intro之前的服务器是 Ubuntu 18.04 &#xff0c;上周周末想升级一下服务器系统&#xff0c;从 18.04 升级到 20.04&#xff0c;结果升级升挂了... 后来 SSH 始终连不上&#xff0c;索性删除重新部署了一个&#xff0c;新部署了一个 Centos 8 的系统&#x…

c++——优先队列(priority_queue)

优先队列详解/C 优先队列 1.概念:什么是优先队列呢?在优先队列中&#xff0c;元素被赋予优先级&#xff0c;当访问元素时&#xff0c;具有最高级优先级的元素先被访问 .即优先队列具有最高级先出的行为特征。它可以说是队列和排序的完美结合体&#xff0c;不仅可以存储数据&am…

一个div 上下两行_Django 实战 | 搭一个 GitHub 用户展示网站 02

一、创建公共 HTML 模板在 templates 文件里面新建一个 base.html&#xff0c;再到Bootstrap4中文文档找到 最基本的模板&#xff0c;拷贝代码到 base.html&#xff0c;在 home.html 中引入 base.html&#xff1a;{% extends base.html %}{% block content %}<h1>Hello W…

C#如何回到主线程,如何在委托指定线程执行

在多线程情况下&#xff0c;有时候我们需要在主线程里面执行一些逻辑&#xff0c;比如修改UI控件SynchronizationContex可以帮助我们在指定的线程执行SynchronizationContext.Current 为获取当前线程的同步上下文&#xff0c;拿到线程的上下文之后可以通过调用Send&#xff08;…

算法设计与分析——递归与分治策略——循环日程赛

问题描述&#xff1a; 非递归方案一&#xff1a;代码 #include<bits/stdc.h> using namespace std;void gameTable(vector<vector<int>> &vec,int k) {int i0,j0;//二维数组的下标&#xff0c;行&#xff0c;列 int temp;//需要新安排选手数目 int n;//…

linux开发板推荐_【新品发布】WiFi开发板XW-01-Kit,超低功耗,冷启快联,智能门锁首选!...

智能门锁作为智能家居的入口级产品以及家庭智能安防的核心单品&#xff0c;已然成为智能家居生态链中不可或缺的核心组成部分。智能门锁方案的研发仍然面临着诸多痛点&#xff0c;如耗电问题、连接繁琐和安全隐患等。物联网的应用与发展必然离不开对更低功耗的追求&#xff0c;…

如何使用 C# 扩展方法

译文链接&#xff1a;https://www.infoworld.com/article/3130492/how-to-work-with-extension-methods-in-c.htmlC# 在 3.0 版本中提供了对 扩展方法 的支持&#xff0c;扩展方法常用于给一个已存在的类添加新的方法从而扩展该类的功能&#xff0c;最关键的是&#xff1a;你不…

算法设计与分析——递归与分治策略——最接近点对问题

【问题描述】 最近对问题要求在包含有n个点的集合S中&#xff0c;找出距离最近的两个点。设 p1(x1,y1)&#xff0c;p2(x2,y2)&#xff0c;……&#xff0c;pn(xn,yn)是平面的n个点。 严格地将&#xff0c;最近点对可能不止一对&#xff0c;此例输出一对即可。 【基本算法思想…

Visual Studio 即时窗口实用技巧

在 Visual Studio 中有一个窗口叫 Immediate 窗口&#xff0c;中文版本应该叫即时窗口。默认会在你启动调试时在 VS 编辑器中弹出来。你也可以通过 Debug|Windows|Immediate 或者使用快捷键 CtrlAltI 手动把它调出来。这个窗口很实用&#xff0c;尤其是在调试的时候。下面总结几…

怎么判断再一个局域网内一个ip被两台机器占用_交换机与 VLAN 到底是怎么来的...

最近有几个学生粉丝后台私信我&#xff0c;让我说说交换机与 VLAN。我在阅读这几个粉丝私信中发现一个有趣的现象&#xff0c;那就是吐槽大学计算机网络课程的晦涩枯燥&#xff0c;而不是去深层次解释协议出现的原因或者用来去解决什么问题。帅天今天就和大家聊聊交换机与 VLAN…

移动建模平台元数据存储架构演进

源宝导读&#xff1a;明源云天际-移动建模平台是一个快速生成多端移动应用的PaaS平台&#xff0c;元数据是移动应用设计与运行的核心数据结构&#xff0c;本文将从元数据存储这个视角分享我们的技术思考与实践。一、什么是元数据&#xff08;Metadata&#xff09;&#xff1f;这…

浅谈AsyncLocal,我们应该知道的那些事儿

【导读】最近查看有关框架源码&#xff0c;发现AsyncLocal这玩意水还挺深&#xff0c;于是花了一点功夫去研究&#xff0c;同时对比ThreadLocal说明二者区别以及在何时场景下使用AsyncLocal或ThreadLocalThreadLocal相信很多童鞋用过&#xff0c;但AsyncLocal具体使用包括我在内…