线性时间选择算法(Java)

  • 线性时间选择算法
    • 随机划分线性选择
      • 分析
      • 代码
    • 利用中位数线性时间选择
      • 分析
      • 例题
      • 代码

线性时间选择算法

最近算法课的知识点之一,自己以前没遇见过(是我菜了没错),这次写一篇。

那么什么是线性时间选择呢???一句话,在线性时间内完成选择

一般情况下是这样的,我们想要找出一个数组中的最大值或最小值,那就只需要一次排列,然后输出第一个或最后一个元素就行了,但如果是要找出一个数组中的第k小的元素呢?

  1. 在某些特殊情况下,很容易设计出解选择问题的线性时间算法。如:当要选择最大元素或最小元素时,显然可以在O(n)时间完成。(遍历一次)

  2. 一般的选择问题,特别是中位数的选择问题似乎比最小(大)元素要难。但实际上,从渐近阶的意义上,它们是一样的。也可以在O(n)时间完成。

之前我记得我更过一篇,里面说到就是先排个序,然后通过下标去得到,因此这个问题的解决效率取决于排序算法的效率。

但是现在不一样了,我们有了更好的办法。

随机划分线性选择

分析

随机划分线性选择。模仿快速排序算法,对数组在left——right范围内进行一次划分(partition方法,我们这里默认采用随机元素为基准),得到基准下标i,不大于基准的在左边,比基准大的在右边。计算出left——i(包含i)中有多少个元素(j),与k进行比较。

  1. 如果k<j,说明当前left——right中第k小的在左边序列中,那么从left——i-1继续上述步骤寻找第k小。
  2. 如果k=j,说明基准i就是left——right中第k小,返回a[j]。(因为前面的都不大于它,后面的都大于它,不管左边是序列怎么排的,整体第k(j)小就是他)
  3. 如果k>j,说明第k小在右边序列,大于基准a[i],那么从i+1——right继续划分,并将k改为k-j。(整体序列提出了前j个元素,那么第k小在剩下的序列中就是第k-j小了)

一直到left=right的时候就可以返回a[left]了(其实我觉得如果有上述2的情况的话就不需要这个了)

这是课堂上PPT给的思路

这是算法导论的(就是我刚刚说的)

代码

    /** @Title randomizedSelect* @Description 基于随机元素为基准的线性时间选择* @author 滑技工厂* @Date 2020/3/26* @param [a, L, R, k -> L---R中的第k小]* @return int* @throws*/public static int randomizedSelect(int[] a, int L, int R, int k) {if (L == R)return a[L];//获取为基准的随机元素的下标int i = randomizedPartition(a, L, R);//j为划分后左序列到基准(包含基准)的元素个数int j = i - L + 1;if (k < j)//如果k小于j,说明在基准i的左边return randomizedSelect(a, L, i - 1, k);else if (k == j)//return a[i];else//k大于j 说明在i的右边序列return randomizedSelect(a, i + 1, R, k - j);}

利用中位数线性时间选择

分析

算法的思路:如果能在线性时间内找到一个划分基准使得按这个基准所划分出的2个子数组的长度都至少为原数组长度的ε倍(0<ε<1),那么就可以在最坏情况下用O(n)时间完成选择任务。例如,当ε=9/10,算法递归调用所产生的子数组的长度至少缩短1/10。所以,在最坏情况下,算法所需的计算时间T(n)满足递推式T(n)<=T(9n/10)+O(n)。由此可得T(n)=O(n)。

先描述下过程。
将n个输入元素划分成n/5个组,每组5个元素,最只可能有一个组不是5个元素。用任意一种排序算法,将每组中元素排好序,并取出中位数,共n/5个。

递归调用Select来找出这n/5个元素中的中位数。如果n/5是个偶数,就找它两个中位数中较大的一个。以该元素作为划分基准。

这种情况下,找出的基准x至少比3(n-5)/10个元素大,同理也比3(n-5)/10个元素小。(下图中箭头指向是从大到小,红+蓝的数量为3(n-5)/10)而当n>=75时,3(n-5)/10>=n/4所以按此基准划分所得的两个子数组的长度都至少缩短1/4

得到划分基准后,后面就和第一个一样,计算左序列个数,和k进行比较。判断在左序列还是右序列,在递归调用该方法(k在右序列仍要减j),直到k=j为止,返回那个基准。

例题



代码

    /** @Title select* @Description 利用中位数线性时间选择* @author 滑技工厂* @Date 2020/3/27* @param [a, l, r, k]* @return int* @throws*/public static int select(int[] a, int l, int r, int k) {if (r - l < 75) {insertSort(a, l, r);    //用插入排序进行排序return a[l + k - 1];}int group = (r - l + 5) / 5;for (int i = 0; i < group; i++) {int left = l + 5 * i;int right = (l + i * 5 + 4) > r ? r : l + i * 5 + 4;  //如果超出右边界就用右边界赋值int mid = (left + right) / 2;insertSort(a, left, right);swap(a, l + i, mid);     // 将各组中位数与前i个}int pivot = select(a, l, l + group - 1, (group + 1) / 2);  //找出中位数的中位数int p = partition(a, l, r, pivot);    //用中位数的中位数作为基准的位置int j = p - l + 1;       //leftNum用来记录基准位置的前边的元素个数if (k == j)return a[p];else if (k < j)return select(a, l, p - 1, k);else                    //若k在基准位子的后边,则要从基准位置的后边数起,即第(k - leftNum - 1)个return select(a, p + 1, r, k - j - 1);}

详细代码去我的G站

作业又完成了一个 (^-^)V

线性时间选择算法(Java)相关推荐

  1. Top k问题(线性时间选择算法)

    问题描述:给定n个整数,求其中第k小的数. 分析:显然,对所有的数据进行排序,即很容易找到第k小的数.但是排序的时间复杂度较高,很难达到线性时间,哈希排序可以实现,但是需要另外的辅助空间. 这里我提供 ...

  2. 线性时间选择算法的分治思想:邮局选址问题和士兵战队问题

    一. 实验题目 1. 邮局选址问题 在一个按照东西和南北方向划分成规整街区的城市里,n 个居民点散乱地分 布在不同的街区中.用 x 坐标表示东西向,用 y 坐标表示南北向.各居民点的 位置可以由坐标( ...

  3. 线性时间选择【递归分治法】

    顾名思义:这篇文章讲解的就是如果用线性时间算法来作出元素选择问题. 问题描述:给定线性序集中n个元素和一个整数k,1<=k<=n.要求找出这n个元素中第k小的元素,即如果将这个n个元素依其 ...

  4. 算法笔记——【分治法】线性时间选择

    线性时间选择问题:给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k小的元素,(这里给定的线性集是无序的). 随机划分线性选择 线性时间选择随机划分法可以模仿随机化快速排序算法设 ...

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

    顾名思义:这篇文章讲解的就是如果用线性时间算法来作出元素选择问题. 问题描述:给定线性序集中n个元素和一个整数k,1<=k<=n.要求找出这n个元素中第k小的元素,即如果将这个n个元素依其 ...

  6. 线性时间选择-分治算法

    问题描述  给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k小的元素.在线性时间内O(n)? k=1; 最小元素 O(n) k=n; 最大元素 O(n) k=(n+1)/2: ...

  7. 数据结构和算法(Java)-张晨光-专题视频课程

    数据结构和算法(Java)-579人已学习 课程介绍         如果说各种编程语言是程序员的招式,那么数据结构和算法就相当于程序员的内功. 想写出精炼.优秀的代码,不通过不断的锤炼,是很难做到的 ...

  8. 线性查找法java代码_Java线性查找和二分查找

    Java线性查找和二分查找. 一 线性查找 定义:在一列给定的值中进行搜索,从一端开始逐一检查每个元素,直到找到所需元素的过程. 线性查找又称为顺序查找.如果查找池是某种类型的一个表,比如一个数组,简 ...

  9. 数据结构与算法-java笔记一 更新中

    数据结构与算法-java笔记一 更新中 数据结构与算法 什么是数据结构.算法 数据结构学了有什么用: 线性结构 数组 特点 应用 链表 存储结构 链表类型 单链表 双向链表 双向循环链表 链表与数组的 ...

  10. 排序算法python实现_合并排序算法– Java,C和Python实现

    排序算法python实现 Merge sort is one of the most efficient sorting algorithms. It works on the principle o ...

最新文章

  1. 【Linux 内核】进程管理 ( 进程相关系统调用源码分析 | fork() 源码 | vfork() 源码 | clone() 源码 | _do_fork() 源码 | do_fork() 源码 )
  2. final关键字的几大特征
  3. Windows下MetaMap工具安装
  4. Spring Boot和Swagger UI
  5. mysql文件_mysql 的各种文件详细说明
  6. AndroidStudio安卓原生开发_UI控件_Spinner用法_下拉选择框---Android原生开发工作笔记100
  7. python画roc曲线需要什么数据,Python ROC曲线绘制
  8. Alluxio部署(local模式)
  9. iOS开发之原生二维码扫描rectOfInterest扫描区域
  10. Quartus II 与ModelSim-Altera联合仿真PLL
  11. ZigBee 协议栈的调度顺序代码分析
  12. python 官方中文文档(在线)
  13. 【高性能计算背景】《并行计算教程简介》翻译 - 中文 - 1 / 4
  14. element-ui表格的滚动条样式修改(当固定table表格高度时默认滚动条样式太丑)
  15. 不会做动画的程序猿不是好的动画师(如何用css3动画做动画)
  16. 用Excel表格拆分一行里的内容
  17. 【Mac】快捷键锁屏
  18. usb gaghet hid 模拟鼠标键盘的绝对值描述
  19. 区别:KL散度,JS散度,Wasserstein距离(EMD)
  20. 初学以太坊--环境搭建篇

热门文章

  1. Python 破解验证码
  2. github上看到的springboot做的后台管理系统,bootdo,适合大家学习入门
  3. 为什么人人都应该学编程?
  4. win10下编译GANet
  5. QQ音乐sign解密以及排行榜完整歌曲数据
  6. 如何解除国外听QQ音乐网易音乐地区版权限制解除
  7. 24点自动出题,可打印,A4排版
  8. 京东自动化签到脚本-京东休闲游戏自动化签到助手
  9. 用户故事与敏捷方法笔记---搜集故事
  10. easyui框架tabs控件