参考视频bilibil fjnuzs

文章目录

  • 一、题目分析
  • 二、计算思路伪代码
  • 三、Java实现
  • 四、时间复杂度

一、题目分析

给出一个n个元素的序列,求其中的第k小元素(即序列按升序排序后的第k个元素)

如果用排序时间复杂度nlogn,随机快速排序时间复杂度n。

但是这里采用一种分治的方法使时间复杂度为n。若分治算法中,每次分解子问题后,只取其中一个子问题解之,丢弃其余的子问题。每次递归调用,问题的规模以常数因子被减小。设分解问题只需线性时间,则算法的时间复杂性满足 Θ n \Theta n Θn。

二、计算思路伪代码

大致思路是选一个“主元”,比他大的放一个数组,比他小的放另一个数组,等于的再放一个数组。然后每个数组都有长度,子问题就变为k所在的那个数组,其余两数组便可以舍去。直到只有44个元素时就去排序找第K。(为啥是44哩,是在计算时间复杂度时确定的)
还有一个难度是找到“主元”就是一个中间的数,避免子问题太大,被舍弃的内容太少。找主元的方式是五个一组,不够5个舍弃掉,将每五个的中间数放入mid数组,再从mid数组里找一个中间数作为主元(mm)。

//求A[low.high]中的第k小元素并返回。
select ( A, low, high, k )  p=high-low+1              //p为当前处理的元素个数。if p<44 then           // 当元素个数<44时,直接求解。将A[low..high]排序return(A[low+k-1])end if//以下分解子问题q= p/5下取整将A[low.low+5q-1]分为q组,每组5个元素将q组中的每一组单独排序并找出中项,所有的中项存于数组Mid[1..q]中mm=select(Mid , 1, q, q/2上取整)        //求中项序列M的中项mm将A[low..high]分成三组A1={a|a<mm} , A2={a|a=mm}, A3={a|a>mm}//以下选择一个子问题递归或直接解。case|A1|>=k: return select (A1,1, |A1|, k)|A1|+|A2|>=k: return mm|A1|+|A2|<k: return select (A3,1, |A3|, k-|A1|-|A2| )end case
end select

三、Java实现

但是有一个不足,就是我测试的数据没有找到大于44的(lan)所以只能算跟着伪代码码了一遍。

public class TestMink {public static void main(String[] args) {int[] arr = {56, 34, 22, 7, 16, 95, 46, 37, 81, 12, 73, 26, 19, 31, 68, 42, 3, 72, 51};System.out.println(select(arr, 0, arr.length-1, 8));}public static int select(int[] arr, int begin, int end, int k) {//传的是下标int p = end-begin+1;if (p < 44) {Arrays.sort(arr);return arr[begin+k-1];}int q = (int)Math.floor(p/5);int mm = medians(arr, begin, q);//起始下标和一共多少组int[] a1 = new int[end-begin+1];int[] a2 = new int[end-begin+1];int[] a3 = new int[end-begin+1];int count1 = 0;int count2 = 0;int count3 = 0;for(int i=begin; i<=end; i++) {if(arr[i] < mm) {a1[count1++] = arr[i];}else if(arr[i] > mm) {a3[count3++] = arr[i];}else {a2[count2++] = arr[i];}}if(count1 >= k ) {return select(a1, 0, count1, k);}else if(count1+count2 >= k) {return mm;}else {return select(a3, 0, count3, k-count1-count2);}}//找主元public static int medians(int[] arr, int low, int q) {int[] mArr = new int[q];int j = 0;int count = 0;int[] temp = new int[5];for (int i = low; i < low+5*q-1; i++) {if(count == 5) {count = 0;Arrays.sort(temp);mArr[j++] = temp[2];}else {temp[count++] = arr[i];}}return select(mArr, 0, mArr.length - 1, mArr.length / 2);}
}

四、时间复杂度

select函数两个地方被调用,在找主元时递归的规模是n/5,还有就是舍弃两个数组递归去解决子问题时。a1和a3的规模采用估算。

T ( n ) ⩽ { c , n < 44 T ( ⌊ n / 5 ⌋ ) + T ( ⌊ 3 n / 4 ⌋ ) + c n , n ≥ 44 T(n) \leqslant \begin{cases} c &,n < 44\\ T(\lfloor n/5 \rfloor) + T(\lfloor 3n/4 \rfloor)+cn &,n\ge44 \end{cases} T(n)⩽{cT(⌊n/5⌋)+T(⌊3n/4⌋)+cn​,n<44,n≥44​
解的 T ( n ) ⩽ 20 c n T(n)\leqslant20cn T(n)⩽20cn

第K小元素 时间复杂度n相关推荐

  1. 求第k小元素:采用特定分治策略

    问题[描述算法问题,首选形式化方式(数学语言),其次才是非形式化方式(日常语言)]设L是n个元素的集合,从L中选取第k小的元素,其中1<=k<=n.这里的第k小元素是指,当L按从小到大排好 ...

  2. 寻找中项和第k小元素c语言,分治法第k小元素poj2104.ppt

    分治法第k小元素poj2104 第六章 分 治 6.1 引言 分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之. 战略 算法设计技术 划分--治理- ...

  3. 二叉搜索树第k小元素

    二叉搜索树第k小元素 二叉搜索树的中序遍历是一个递增的序列(左根右) 中序遍历完整二叉搜索树,每次将遍历到的节点存入数组中去,找到第k - 1个节点返回即可 k是从下标1开始的,存到结果数组res中, ...

  4. 分治算法 求第k小元素 O(n) O(nlog2^n)

    BFPRT算法:时间复杂度O(n)求第k小的数字(分治算法+快排) 各位小伙伴,由于本篇文章代码太过杂乱.我于 2018年12月25日 对文中介绍的算法进行了重写.点击上面的蓝色字体,可以阅读重写后的 ...

  5. 快速排序_查找第k小元素

    快速排序_查找第k小元素 以下代码可以从数组a[]中找出第k小的元素. 它使用了类似快速排序中的分治算法,期望时间复杂度是O(N)的. 请仔细阅读分析源码,填写划线部分缺失的内容. 一个问题,快排你的 ...

  6. 练习六(归并排序、第k小元素、棋盘覆盖、大整数乘法)

    文章目录 题目 数组合并 归并排序 第k小元素问题 找中位数 棋盘覆盖问题 大整数乘法 题目 数组合并 题目描述 编写一个程序,将两个有序数组合并成一个更大的有序数组,要求时间复杂度为O(n). 输入 ...

  7. 解决寻找第K小元素问题——三种不同的算法实现

    个人原创,禁止转载--Zetrue_Li 问题描述:在一个序列里找出第K小元素 以下程序基于函数 int select_kth_smallest(list q, int k) 实现 :返回向量q中第k ...

  8. 分治法实验-寻找第k小元素

    问题描述 随机生成含有n个不同元素的数组L(n≥10000),要求找出第k小的元素(k≤n),完成下面的任务: (1)设计一个基于排序选择算法程序,编程调试正确(排序算法自己确定). (2)设计一个时 ...

  9. 算法-寻找第k小元素(C)

    序言 刚开始我认为,寻找第k小的元素:简单呀,先对所有元素排序,之后再找不就完事啦,这时时间复杂度在O(nlgn).那有没有更好的排序的方法了呢?答案:当然是有的. 算法基本思路: (1) 当规模小于 ...

最新文章

  1. gtx1080 驱动 linux,CentOS 7安装Nvidia GTX1080显卡驱动
  2. 也许你不知道的c#基本数据类型及其默认值
  3. 以Drools5.5为例说明“规则引擎在业务系统中应用”---起始篇
  4. 智慧交通day04-特定目标车辆追踪03:siamese在目标跟踪中的应用-DaSiamRPN(2018)
  5. AssetsLibrary使用介绍
  6. java 方法 示例_Java语言环境getDisplayVariant()方法与示例
  7. Kotlin 能取代 Java 吗?
  8. Sublime Text3 安装svn插件遇到的问题
  9. python曲线和直线的交点_求直线与分段线性曲线的交点
  10. 推荐一个在线视频学习、在线试题练习、在线同步考试开源系统
  11. USSD设置呼叫转移功能
  12. 大气数据计算机仿真算法,自适应光学系统中大气湍流的模型分析与计算机仿真...
  13. 配置Jenkins及下载相关插件
  14. wps底板颜色怎么去掉_wps怎么把复制网页的灰色阴影去掉 底纹去掉方法
  15. python破解wifi密码软件下载-python暴力获取wifi密码
  16. 刘涛入职阿里,年薪超过欧阳娜娜!揭秘阿里巴巴的明星员工和职级薪资!
  17. 泛微OA使用笔记-架构
  18. 物联网卡的6个应用案例全面解析
  19. fullpage初使用
  20. 电热毯UL964标准上架亚马逊所需资料流程

热门文章

  1. amis框架实现sdk中使用tsx
  2. 前后端分离框架的实用及优点
  3. 微信小游戏html5教程,微信小游戏白鹭引擎插件使用教程
  4. 贵阳初中生计算机学校,贵州省2021公办的计算机学校
  5. css设置不显示超出内容_显示...,css设置内容超出后显示省略号
  6. python下载的whl文件如何安装呢
  7. Tensorflow和Gensim里word2vec训练
  8. 想转行,为什么首选软件测试?
  9. (USB系列三)stm32 CubeMX usb音频描述符详解 usb audio UAC
  10. 以前小瞧了PPT的SmartArt功能!没想到它是个万能神器!太好用了