【AcWing-Python-786】第k个数/快速选择算法

news2024/9/29 3:28:46
题目: https://www.acwing.com/problem/content/788/
对应视频讲解: https://www.acwing.com/video/228/

题目描述


回顾快排

【AcWing-Python-785】快速排序 - CSDN博客

(一)步骤

  1. 找到分界点x:可以是区间最左端点、区间最右端点、或区间中点

  1. 将整个区间划分为两段,使得左边所有数Left ≤ x,右边所有数Right ≥ x【注意分界点位置的值不一定为x】

  1. 递归排序Left,递归排序Right

(二)时间复杂度

排序的时间复杂度是O(n * logn),快速排序的时间复杂度是O(n)

(三)与快选的联系

经过步骤1和2后,整个区间里,在分界点左边的数都≤x(假设长度为SL),右边的数都≥x(假设长度为SR)。现在想找到第k大的数

  • 若 k ≤ SL,则整个区间第k小的数一定在左边,此时只需递归处理左边即可

  • 若 k >SL,则整个区间第k小的数一定在右边,此时只需递归处理右边即可

快排需要递归左右两边,而快选只需要递归一边即可

快选的时间复杂度为O(n)

  • 先对整个区间划分两部分,使左边都≤x,右边都≥x,这步需要扫描整个区间n,故为O(n)

  • 根据第k小的数的k,与左边区间的长度SL的大小关系,判断是递归处理左边还是右边,只需扫描一半的区间即可,故为O(n/2)

  • 以此类推,n + n/2 + n/4 + n/8 + ... = n (1 + 1/2 + 1/4 + 1/8 + ...) ≤ 2n,故为O(2n),因为常数不影响,故还是O(n)


解题思路及代码

(一)思路

首先明确,第k大的数X在有序数组中的位置为k-1(i ∈ [0, n-1])

采用快排分治思想,每次可只处理X所在的那一半区间,所以在进行快排找分界点时,找到此次递归的数组分界点j,将此次递归区间 [l, r] 分为 [l, j] 和 [j+1, r] 左右两个区间,并确定左右区间中的数,这些数在有序数组中也处于该区间,这样就可以根据j来确定k-1在左区间还是在右区间

  • 如果 k - 1 <= j,说明k - 1在左区间,则递归处理左区间,舍去(不处理)右区间

  • 反之如果k - 1 > j,说明k - 1在右区间,则递归处理右区间,舍去(不处理)左区间

不断递归,区间长度为1时,则找到了在有序数组中下标为k-1的数X

(二)代码

n, k = map(int, input().split())
nums = list(map(int, input().split()))

def quick_sort(arr, left, right):
    
    if left >= right:
        return
    
    i, j, x = left-1, right+1, arr[(left+right)//2]
    
    while i < j:
        i += 1
        j -= 1
        
        while arr[i]<x:
            i += 1
        while arr[j]>x:
            j -= 1
        
        if i<j:
            arr[i], arr[j] = arr[j], arr[i]   
    
    # 此时j左边都是≤x的数,j右边都是≥x的数
    # 要找到排序后第k小的数,也即下标为 k-1 的数
    if k-1 <= j:
        quick_sort(arr, left, j)
        
    if k-1 > j:
        quick_sort(arr, j+1, right)

quick_sort(nums, 0, n-1)
print(nums[k-1])

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

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

相关文章

java String类(超详细,含常用方法、面试题,内存图,案例)

String类一、String类的特点二、String 类的常见构造方法三、String常见的面试题1.字符串常量池2.String s "abc"与String s new String("abc")区别3.字符拼接4.常量优化机制四、String常用方法1. 比较字符串内容2. 遍历字符串3.截取字符串4.替换字符串5…

Linux-常见命令

&#x1f69c;关注博主&#xff1a;翻斗花园代码手牛爷爷 &#x1f699;Gitee仓库&#xff1a;牛爷爷爱写代码 目录&#x1f692;xshell热键&#x1f697;Linux基本命令&#x1f697;ls指令&#x1f695;pwd指令&#x1f696;cd指令&#x1f68c;touch指令&#x1f68d;mkdir指…

C++11多线程编程 一:多线程概述

1.1 第一个线程代码示例-线程创建示例 多线程编程当中&#xff0c;每一个程序运行都至少会有一个线程&#xff0c;一般的main函数都作为主线程的入口&#xff0c;这里面是一个进程包含一个主线程&#xff0c;一个进程里面包含多个子线程&#xff0c;所以一般在主线程当中(也就是…

【离线数仓-8-数据仓库开发DWD层设计要点-交易域相关事实表】

离线数仓-8-数据仓库开发DWD层设计要点-交易域相关事实表离线数仓-8-数据仓库开发DWD层设计要点-交易域相关事实表一、DWD层设计要点二、交易域相关事实表1.交易域加购事务事实表1.加购事务事实表 前期梳理2.加购事务事实表 DDL表设计分析3.加购事务事实表 加载数据分析1.首日全…

Nginx 和 Tomcat 实现负载均衡

Nginx 和 tomcat 实现负载均衡 &#x1f3c6;荣誉认证&#xff1a;51CTO博客专家博主、TOP红人、明日之星&#xff1b;阿里云开发者社区专家博主、技术博主、星级博主。 &#x1f4bb;微信公众号&#xff1a;微笑的段嘉许 &#x1f4cc;本文由微笑的段嘉许原创&#xff01; &am…

【模拟集成电路】电荷泵(CP)设计

电荷泵&#xff08;CP&#xff09;设计前言一、电荷泵&#xff08;CP&#xff09;原理&#xff08;1&#xff09;电流失配问题&#xff08;2&#xff09;开关管的时钟馈通问题&#xff08;3&#xff09;电荷注入问题二、电荷泵&#xff08;CP&#xff09;电路三、电荷泵性能测试…

springboot+jersey+tomcat实现跨域方式上传文件到服务器

前言 在服务器上&#xff0c;当我们启动了tomcat&#xff0c;就可以以 http://ip地址:8080/文件路径/文件名 的方式&#xff0c;进行访问到我们服务器上处于tomcat的webapps文件夹下的文件 于是为了可以往上面加文件&#xff0c;我们有两种方式&#xff0c;一种就是直接复制文…

ABAP 辨析CO|CN|CA|NA|CS|NS|CP|NP

1、文档说明 本篇文档将通过举例&#xff0c;解析字符的比较运算符之间的用法和区别&#xff0c;涉及到的操作符&#xff1a;CO|CN|CA|NA|CS|NS|CP|NP 2、用法和区别 用法总览 以下举例&#xff0c;几乎都使用一个字符变量和一个硬编码字符进行对比的方式&#xff0c;忽略尾…

OAK相机如何将yoloV7模型转换成blob格式?

编辑&#xff1a;OAK中国 首发&#xff1a;oakchina.cn 喜欢的话&#xff0c;请多多&#x1f44d;⭐️✍ 内容可能会不定期更新&#xff0c;官网内容都是最新的&#xff0c;请查看首发地址链接。 ▌前言 Hello&#xff0c;大家好&#xff0c;这里是OAK中国&#xff0c;我是助手…

centos7安装

centos7安装制作U盘启动盘下载镜像下载 UltralISO制作启动盘使用U盘安装系统修改模式为 UEFI调整BOOT option保存重启进入安装界面安装图形界面安装搜狗输入法制作U盘启动盘 下载镜像 去官网下载镜像&#xff0c;找到 mirrors链接&#xff08;速度快&#xff09; 选择一个中…

OpenAI是什么

OpenAI是一家非营利性人工智能研究公司&#xff0c;致力于研究人工智能和其他机器学习技术。OpenAI 会和谷歌、苹果、IBM 等知名公司创办的其它一系列项目一道探索先进计算机技术&#xff0c;解决面部识别或语言翻译等问题。 OpenAI 是由马斯克、奥特曼等人 2015 年联合创办的人…

奔四的路上,依旧倔强的相信未来

本文首发于2022年12月31日 原标题: 奔四的路上,依旧倔强的相信未来!–我的2022年终总结 读大学那几年,一直保持着写日记和做计划的习惯,还记得大学毕业刚开始打工的时候,我的床头的墙上一定会画一张表,写上一个月的计划和一周的计划 计划也会有完不成的时候,但加深了…

【Hello Linux】初识冯诺伊曼体系

作者&#xff1a;小萌新 专栏&#xff1a;Linux 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;简单介绍冯诺伊曼体系 冯诺伊曼体系 冯诺伊曼体系结构的合理性 我们在Linux的第一篇博客中讲解了第一台计算机的发明是为了解决导弹的…

实例7:树莓派呼吸灯

实例7&#xff1a;树莓派呼吸灯 实验目的 通过背景知识学习&#xff0c;了解digital与analog的区别。通过GPIO对外部LED灯进行呼吸控制&#xff0c;熟悉PWM技术。 实验要求 通过python编程&#xff0c;用GPIO控制LED灯&#xff0c;使之亮度逐渐增大&#xff0c;随后减小&am…

交换字符使得字符串相同[贪心]

贪心前言一、交换字符使得字符串相同二、贪心1、分析问题的思路过程2、go总结参考资料前言 贪心算法&#xff0c;必须先看清楚有哪些选择&#xff0c;才能在这些选择的基础上进行贪心&#xff0c;做最优选择&#xff0c;除此之外&#xff0c;还得看局部最优会不会形成全局最优…

8 百度接口

0 建议学时 2学时 1 简介 百度人工智能平台-站在巨人的肩膀上 https://ai.baidu.com/ 控制台->立即注册 百度人工智能平台 APP Key 和 Secret Key AI接入指南 https://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjgn3 百度智能云视频参考 https://abcxueyuan.baidu.com/#/…

2023年最新详细教程!手把手教你搭建Hexo + GitLab个人博客

文章目录前言一、安装和配置环境1.安装 Git2.安装 Node.js二、新建博客项目1.GitLab配置CI/CD自动化部署1.1 GitLab新建项目1.2 GitLab自建Runners1.2.1 下载gitlab-runner1.2.2 注册Runners1.2.3 安装Runners并启动1.3 添加.gitlab-ci.yml文件2.拉取和推送hexo blog2.1 拉取he…

基于遗传算法的配电网故障定位(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密…

sonarqube 外部扫描器 go vet golangci-lint 无法导入问题

首先&#xff0c;请看[外部分析报告]各种语言的报告生成 go vet 2> govet-report.out#没有golangci-lint&#xff0c;我从网上找到了 golangci-lint run --out-format checkstyle ./... > golangci-lint-report.xml值得注意的是&#xff0c;貌似不支持目录&#xff0c;仅…

6.2 负反馈放大电路的四种基本组态

通常&#xff0c;引入交流负反馈的放大电路称为负反馈放大电路。 一、负反馈放大电路分析要点 如图6.2.1(a)所示电路中引入了交流负反馈&#xff0c;输出电压 uOu_OuO​ 的全部作为反馈电压作用于集成运放的反向输入端。在输入电压 uIu_IuI​ 不变的情况下&#xff0c;若由于…