文章目录

  • Leetcode 215. Kth Largest Element in an Array
    • 1.1:快速选择算法流程
    • 1.2:注意事项
    • 1.3:python实现
  • Leetcode 973. K Closest Points to Origin
    • 1.1 题意
    • 1.2 思路
    • 1.3 python实现
  • 3. 牛客:最小的K个数
    • 3.1 题意:
    • 3.2 分析
    • 3.3 python实现
  • 最后:heapq模块实现top N---nlargest()和nsmallest()函数

Leetcode 215. Kth Largest Element in an Array

题意:给定一个无序的数组,寻找第K大的元素。

1.1:快速选择算法流程

输入:
nums = [3,2,1,5,6,4]
k=2

  • step 1: 随机选择一个 pivot,通过一系列计算,查看是否是我们需要找到的 Top k 对应的 pivot
  • step 2: 把 pivot 移动到最右的位置,以最右为标杆,从头开始对剩余部分进行选择查找
  • step 3: 定义两个指针,初始化为0,查看 j 所在的指针是否小于等于 pivot,4 大于 3,所以我们把 j 指针右移一位
  • step 4: 查看 j 所在的指针是否小于等于 pivot,2 小于等于 3,我们替换 i 指针和 j 指针所在的位置,同时把 i 和 j 指针都右移一位。
  • step 5: 查看 j 所在的指针是否小于等于 pivot,1 小于等于 3,我们替换 i 指针和 j 指针所在的位置,同时把 i 和 j 指针都右移一位。
  • step 6: 重复上述步骤,直到 j 指针移动到最右边

  • step 7: 把pivot放到中间来,把数组划分为左右两个部分
  • step 8: 此时 pivot 3 左边的值都小于 3,右边的值都大于 3,pivot 3 对应的是 Top 4 而不是 我们需要找的 Top 2,但我们可以知道,Top 2 一定在 pivot 3 右边的位置。
  • step 9: 把右半部分按照重复执行上述步骤,最终找到 Top 2 的 pivot,对应的值为 5

1.2:注意事项

pivot 的选择很重要,如果对于一个已排序的数组,我们每次都选择最大/最小的值为 pivot,那么时间复杂度为 O(N^2) 。每次通过 random 选择 pivot 可以尽量避免最坏情况发生。

快速选择算法的平均时间复杂度是 O(N),但最坏情况下的时间复杂度是 O(N^2) ,因为我们已经随机选择 pivot,所以能够最大程度上的减少最坏情况发生

1.3:python实现

def findKthLargest(self, nums, k):def quickSelect(nums, lo, hi, k): # 从小到大排序pivot = random.randint(lo, hi) # 0-len(nums)-1中随机取一个下标,避免最坏的情况nums[hi], nums[pivot] = nums[pivot], nums[hi] # 最右边存这个支点i = j = lowhile j < hi:if nums[j] <= nums[hi]: # 找到一个比支点还小的数nums[i], nums[j] = nums[j], nums[i] # i, j相互交换i += 1j += 1 # 每一次j都要前进一步nums[i], nums[j] = nums[j], nums[i] # 把pivot放到中间来if hi > k + i - 1: # Topk在右边return quickSelect(nums, i + 1, hi, k) elif hi < k + i -1: # Topk在左边return quickSelect(nums, lo, i - 1, k - (hi - i + 1))else:return nums[i]return quickSelect(nums, 0, len(nums)-1, k)

Leetcode 973. K Closest Points to Origin

1.1 题意

给定一个二维数组,数组中每一行代表一个点,求距离原点(0,0)最近的K个点

1.2 思路

还是按照以上的快速选择排序算法,稍微做一点点修改

  • 上一题的数组是从小往大排序,最后从右边开始数第K大的元素。
  • 这一题是从大往小排序,最后从右边开始数K个小的元素,返回一个数组。

1.3 python实现

def kClosest(self, points, K):# 从小到大,找的是从右边数的第k大的元素def quickSort(points, lo, hi, k):pivot = random.randint(lo,hi)   #在闭区间里面选择points[hi], points[pivot] = points[pivot], points[hi]i = j = lowhile j < hi: # 从左到右开始遍历if dis(points[j]) > dis(points[hi]): # 修改1:从大往小排序points[i], points[j] = points[j], points[i]  # 交换点i,j,把小数移到左边去i += 1j += 1points[i], points[j] = points[j], points[i]  # 把pivot放在中间来# 以下是根据pivot的位置来进行划分if hi > k + i -1: # i太小了,Topk在右边return quickSort(points, i+1, hi, k)elif hi < k + i - 1: # Topk在左边return quickSort(points, lo, i-1, k-(hi-i+1))else:return points[i:][:]  # 修改2:返回最后的k个最近的点def dis(dot): # 求得距离return dot[0]**2 + dot[1]**2return quickSort(points, 0, len(points)-1, K) # 要的是从左往右的点

3. 牛客:最小的K个数

链接:最小的k个数

3.1 题意:

输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。

3.2 分析

这道题和上一道题"距离原点最近的k个节点"非常类似,因此也可以使用快速选择算法来做,并且时间复杂度很低,O(N)来做了

3.3 python实现

import random
class Solution:def GetLeastNumbers_Solution(self, tinput, k):# write code hereif k <=0 or k > len(tinput) or not tinput: return []def quickSelect(nums, lo, hi, k): # 从小到大排序pivot = random.randint(lo, hi) # 0-len(nums)-1中随机取一个下标,避免最坏的情况nums[hi], nums[pivot] = nums[pivot], nums[hi] # 最右边存这个支点i = j = lowhile j < hi:if nums[j] > nums[hi]: # 找到一个比支点还大的数nums[i], nums[j] = nums[j], nums[i] # i, j相互交换,把大数放后面i += 1j += 1 # 每一次j都要前进一步nums[i], nums[j] = nums[j], nums[i] # 把pivot放到中间来if hi > k + i - 1: # Topk在右边return quickSelect(nums, i + 1, hi, k) elif hi < k + i -1: # Topk在左边return quickSelect(nums, lo, i - 1, k - (hi - i + 1))else:return nums[i:]res = quickSelect(tinput, 0, len(tinput)-1, k)res.sort() # 可能退化为O(N^2)啊!return res

最后:heapq模块实现top N—nlargest()和nsmallest()函数

通过以上快速选择算法选择的top N个元素后,原来的数组的顺序已经打乱了,使用heapq模块取出top N个元素后,不会修改原来的数组的顺序

>>> import heapq
>>> nums=[1,8,2,23,7,-4,18,23,42,37,2]
>>> print(heapq.nlargest(3,nums)) # 从大到小排序
[42, 37, 23]
>>> print(heapq.nsmallest(3,nums))  #从小到大排序
[-4, 1, 2]

Top K 问题的最优解 - 快速选择算法(图解详细教程)相关推荐

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

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

  2. 快速幂算法 超详细教程

    快速幂 求幂运算 快速幂引入 快速幂 二进制 快速幂 指数折半 快速幂的应用 求幂运算 求幂运算大家都不陌生,幂是指数运算的结果,当m是正整数时nᵐ的意义为m个n相乘,n的m次幂也就是n的m次方.用代 ...

  3. linux 6.8 安装教程,CentOS 6.8 7.2 安装图解详细教程

    PS:文章转载,虽然基础,还是希望各位路过看官仔细看后实操一次,您才知道途中有那些坑! 感谢作者整理: 1.安装CentOS 6.8 用光盘成功引导系统,会出现下面的界面 这里选择第一项,安装或升级现 ...

  4. MySQL安装图解详细教程

    1.安装MySQL 2.校验MySQL 注意:安装路径不要包含中文!!!最好使用英文或者拼音. 安装图解如下: 接下来有三个按钮: 第一个按钮表示典型安装(推荐的安装) 第二个按钮表示自定义安装(一般 ...

  5. 什么是计算机嵌套分类汇总,Excel中插入分类汇总的嵌套级别的方法图解详细教程...

    在上文我们讲解了Excel 2010工作表中为一组数据插入一个分类汇总级别的方法,本文则讲解了Excel 2010工作表中插入分类汇总的嵌套级别的方法. Excel 2010工作表中可以在相应的外部组 ...

  6. pythonqt5安装路径配置_PyQt5 安装与环境配置方法图解详细教程

    PyQt5 是用来创建Python GUI应用程序的第三方工具包,它不仅与Python有着良好的兼容性,还可以通过可视化拖拽的方式进行窗体的创建,提高开发人员的工作效率,因此深受开发人员的喜爱.作为一 ...

  7. GitHub修改昵称和用户名(图解详细教程)

    1.登录GitHub.https://github.com/ 2.点击右上角头像>>Settings 3.点击进入Settings后显示的页面即为设置/修改昵称的页面 注意:Profile ...

  8. 找出无序数组中最小的k个数(top k问题)

    2019独角兽企业重金招聘Python工程师标准>>> 给定一个无序的整型数组arr,找到其中最小的k个数 该题是互联网面试中十分高频的一道题,如果用普通的排序算法,排序之后自然可以 ...

  9. 快速选择算法-基于快排

    目录 快速选择算法 例题 算法思路 代码实现 快速选择算法 快速选择,就是在一个无需的数组中查找第k个小的数.我们可以很快的想到可以先将数组排序在进行选择,但时间复杂度为O(nlog⁡n)O(n\lo ...

最新文章

  1. mysql 复合索引 in,MySQL复合索引比主键索引还快,为什么?
  2. python和vb的代码可以通用吗-python和vb哪个简单
  3. C# 对象深拷贝、浅铐贝、直接拷贝(转)
  4. 不是世界不好,而是你见得太少
  5. linux使用设备文件的目录,Linux系统下的/dev目录
  6. 计算机视觉与图像处理面试题,深度学习图像处理算法工程师面试题
  7. python中的property_python中的property属性
  8. B站网站后台工程源码泄露 用户信息还安全吗?
  9. gb/t19011-2013 管理体系审核指南
  10. 电机正反转c语言注释,直流电机正反转C程序.doc
  11. Ubuntu一些名词解释
  12. camera 自动对焦手动对焦
  13. 数字化住宅小区对计算机网络有需求,浅谈智能小区宽带接入及其技术发展趋势...
  14. 小米忙着营销,麻烦带上技术!
  15. lmdb.Error: 路径 : ϵͳ�Ҳ���ָ����·����解决办法
  16. c语言编程的难点,c语言编程的难点
  17. 计算机用鼠标画图,在电脑上用鼠标画画用那个软件好
  18. 黑猫带你学UFS协议第1篇:全网最全UFS协议中文详讲,这份学习框架图,你值得拥有!!!(持续更新中...)
  19. JS UMD深入学习(二)—— node_module是commonjs标准,工程目录是ES6标准
  20. uboot源码分析(基于S5PV210)之启动第一阶段

热门文章

  1. CoCreateInstance 做了什么 菜菜的
  2. php 剪头,今天,为什么要剪头发?
  3. Springboot中@Value的使用详解
  4. popstate_js怎么解决popstate多个页面连续返回问题
  5. 《深入线出MFC》读书笔记(一):必备的Win32程序设计原理
  6. 计算机相关专业混体制的解决方案(事业编之学校与医院)
  7. tamcat服务器的项目配置,服务器配置tomcat部署项目
  8. amba_device使用分析
  9. Xshell 7设置及使用日志记录功能
  10. 阿里云ECS测评之选购指南