文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

经典算法:无序数组寻找第K大的数值

2024-12-03 02:02

关注

给定一个整数数组a, 请返回第K (1<=K<=n) 大的数(包括重复的元素,不用去重),保证答案存在。

示例

  1. 输入 [3,2,1,5,6,4] , 2 
  2. 返回值 5 

2. 常规思路

先对无序数组进行排序,然后对有序数组进行查找。

至于选择什么排序算法,有待确定。

先看一下,各种排序算法的复杂度以及稳定性。

看完上面比较之后,可能你心中已经有了自己的答案。

3. 解题思路

常规思路需要两大步:

  1. 先整体排序
  2. 在有序中查找目标值

那么,针对这道题,我们能不能在排序的过程中就确定目标值呢?

思考一下快排的二分特性:

  1. 先找出一个数值的位置,该数值的左侧比自己小,右侧比自己大(整个数组一分为二)
  2. 再分别进行左、右两部分进行步骤1的操作,直至整个数组有序。

这里需要知道的是,在快排中某个数值左侧比自己小,右侧比自己大。该数值的位置就是在最终有序数组中的位置,也就是说可以在查找中确定目标位置。并且,在本题的处理过程中,平均情况下只处理1/2的数据量。


动图 - 快排算法

快排算法查找过程:

4. Go代码实现

  1. func findKLargest(arr []int, k intint { 
  2.     iflen(arr) == 0 || k > len(arr) { 
  3.         return-1 
  4.     } 
  5.  
  6.     var find func(k int, l, r intint 
  7.     find = func(k int, l, r intint { 
  8.          
  9.         ll := l 
  10.         rr := r 
  11.         target := arr[l] 
  12.  
  13.         // 倒序(第K大使用)排列 是 target >= arr[r]  / target <= arr[l] 
  14.         // 正序(第k小使用)排列 是 target <= arr[r]  / target >= arr[l] 
  15.         for l < r { 
  16.             for l < r && target >= arr[r] { 
  17.                 r-- 
  18.             } 
  19.             arr[l] = arr[r] 
  20.  
  21.             for l < r && target <= arr[l] { 
  22.                 l++ 
  23.             } 
  24.             arr[r] = arr[l] 
  25.         } 
  26.        
  27.         arr[l] = target 
  28.         // k在l的右侧 
  29.         // 为什么 下面无论是在左右侧,第一个参数都是k呢? 
  30.         // 因为,k指的是要找的数值的下标位置(第k大就是下标k-1) 
  31.         // 无论在左右侧,对于数组arr来说,其对应的下标都是固定的 
  32.         // 并且 l/r 每次都会变动,所以k这里是固定的 
  33.         if k > l { 
  34.             // 这里的  l+1, rr 也是数组的下标 
  35.             return find(k, l+1, rr) 
  36.         }elseif k < l { 
  37.             // k在l的左侧 
  38.             // 这里的  ll, l-1 也是数组的下标 
  39.             return find(k, ll, l-1) 
  40.         } 
  41.  
  42.         // 此时目标自位置l处的target,就是第k个大的数值 
  43.         return target 
  44.     } 
  45.  
  46.     // 第k大的数值,对应排序之后就是,数组下标k-1 
  47.     finds := find(k-1, 0, len(arr)-1) 
  48.  
  49.     return finds 

 求第K大,则对数组排序排列。

求第K小,则对数组正序排列。

无论如何,都是从头开始找,这样处理更简单。

 

来源:今日头条内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯