Acwing 786.第K个数

Acwing 786.第K个数

题目描述

786. 第k个数 - AcWing题库

运行代码

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int q[N];

int main()
{
    int n, k;
    scanf("%d%d", &n, &k);
    for (int i = 0; i < n; i ++ ) scanf("%d", &q[i]);
    nth_element(q, q + k - 1, q + n);
    printf("%d ", q[k - 1]);
    return 0;
}

代码思路

  1. 引入头文件和命名空间:#include <iostream> 用于输入输出操作。#include <algorithm> 引入算法库,包含nth_element函数。using namespace std; 允许直接使用标准库中的名称,而无需std::前缀。

  2. 定义常量和变量:const int N = 100010; 定义数组的最大容量。int q[N]; 定义一个足够大的数组来存储输入的整数。

  3. 主函数main:

    • 读取数据:首先,读取两个整数nk,分别代表数组的元素个数和要找的第k小的元素的位置(从1开始计数)。然后,通过一个循环读取n个整数并存储到数组q中。

    • 使用nth_element:nth_element(q, q + k - 1, q + n); 这行代码是关键,它将数组q中的元素进行部分排序,使得第k小的元素(按照默认升序排序的标准)正好位于q[k - 1]的位置。nth_element不会保证整个数组有序,只是保证第k个元素就位,它前面的元素都不大于它,后面的元素都不小于它,这就足够找到第k小的元素。

    • 输出结果:printf("%d ", q[k - 1]); 输出找到的第k小的元素。

  4. 返回0:return 0; 表示程序正常结束。

代码思路总结: 这段代码简洁高效地实现了寻找数组中第k小元素的任务,利用了nth_element函数的高效性,特别适合于当只需要找到一个特定位置的元素而不需要全数组排序的场景,大大提高了算法效率。

另外思路

#include<iostream>
using namespace std;
const int N=1e6+6;
int n;int k;
int q[N];
void qs(int q[], int l, int r){
    if (l>=r)return;
    int x = q[l];int i = l-1;int j = r+1;
    while(i<j){
        do i++;while(q[i]<x);
        do j--;while(q[j]>x);
        if(i < j)swap(q[i], q[j]);
    }
    qs(q,l,j);
    qs(q,j+1,r);
}
int main(){
    cin >> n >> k;
    for(int i = 0; i < n; ++i){
        cin >> q[i];
    }
    qs(q,0,n-1);
    cout << q[k-1];
    return 0;
}

代码思路

  1. 头文件和命名空间:

    • #include<iostream> 用于输入输出操作。
    • using namespace std; 允许直接使用标准库中的名称,如coutcin,而不必加std::前缀。
  2. 常量定义和变量声明:

    • const int N = 1e6 + 6; 定义了一个常量N,用于设定数组的最大容量。
    • int n; int k; 声明了两个整型变量,分别用于存储数组长度和要找的第k小的元素的位置。
    • int q[N]; 定义了一个足够大的数组来存储输入的整数序列。
  3. 快速排序函数qs:

    • 函数接受一个整数数组q[]及其左右边界索引lr作为参数。
    • 选择数组的第一个元素q[l]作为基准值x
    • 初始化两个指针ij,分别位于l-1r+1,用于从两边向中间扫描。
    • 使用循环,在q[i]不大于xq[j]不小于x时,向中间移动这两个指针,并在适当时候交换两者所指的元素,以确保左侧元素都不大于x,右侧元素都不小于x
    • ij交错时,基准值x的最终位置确定在j,此时基准值左侧的元素都小于等于它,右侧的元素都大于等于它。
    • 递归调用qs函数分别对基准值左侧和右侧的子序列进行快速排序。
  4. 主函数main:

    • 读取整数n(数组长度)和k(要找的第k小元素的位置)。
    • 通过循环读取数组q[]中的每个整数。
    • 调用快速排序函数qs(q, 0, n - 1)对数组进行排序。
    • 输出排序后数组中第k小的元素,即q[k-1],因为数组索引是从0开始的。

代码在处理大量数据或极端情况时可能不是最优选择,特别是在快速排序最坏情况下的时间复杂度为O(n^2),虽然平均时间复杂度为O(n log n)。对于寻找第k小的元素,有时候使用快速选择算法(基于快速排序思想的优化版本,避免完全排序)会更高效。

改进思路

将原有的快速排序改为快速选择算法,因为我们的目标不是完全排序数组,而是找到第k小的元素。这样可以减少不必要的比较和交换,提高效率,尤其是在k相对较小的情况下。快速选择算法的关键在于只对与k相关的部分进行排序,具体改进如下:

  1. 修改分区函数:调整分区逻辑,仅保证基准元素到达其最终排序位置,而不需要对整个数组进行排序。
  2. 直接返回第k小的元素:在快速选择过程中,一旦找到正确的分区,直接返回第k小的元素,无需完成整个数组的排序。

改进代码

#include<iostream>
#include<climits>
using namespace std;

const int N = 1e6 + 6;

int partition(int arr[], int l, int r) {
    int pivot = arr[r]; // 选择最右侧元素作为基准
    int i = l - 1;
    for(int j = l; j < r; ++j) {
        if(arr[j] <= pivot) {
            i++;
            swap(arr[i], arr[j]);
        }
    }
    swap(arr[i + 1], arr[r]); // 把基准元素放到正确的位置
    return i + 1;
}

int select(int arr[], int l, int r, int k) {
    if(l == r) return arr[l];
    int pivot_index = partition(arr, l, r);
    if(k == pivot_index) {
        return arr[k];
    } else if(k < pivot_index) {
        return select(arr, l, pivot_index - 1, k);
    } else {
        return select(arr, pivot_index + 1, r, k);
    }
}

int main() {
    int n, k;
    cin >> n >> k;
    int q[N];
    for(int i = 0; i < n; ++i) {
        cin >> q[i];
    }
    --k; // 数组索引从0开始
    cout << select(q, 0, n - 1, k) << endl;
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mac屏幕截图软件

一、简介&#xff08;有小伙伴留言说想要mac的屏幕截图软件&#xff0c;今天给大家分享一个还不错的&#xff09; 1、一个功能丰富的功能丰富的截图工具&#xff0c;具有许多高级功能&#xff0c;免费。用于快速拍摄并将它们组织成集合。Snappy还支持注释&#xff0c;共享&…

Linux操作系统:Spark在虚拟环境下的安装及部署

将Spark安装到指定目录 // 通过wget下载Spark安装包 $ wget https://d3kbcqa49mib13.cloudfront.net/spark-2.1.1-bin-hadoop2.7.tgz // 将spark解压到安装目录 $ tar –zxvf spark-2.1.1-bin-hadoop2.7.tgz –C /usr/local/ // 重命名 $ mv /usr/local/spark-2.1.1-bin-hado…

1.音视频开篇

目录 音视频播放的原理 音视频数据格式YUV YUV数据存储比 ​编辑 YUV空间格式 RGB与YUV转换 音视频播放的原理 主要分为&#xff1a;解协议->解封装->解码->音视频同步->播放。当然&#xff0c;如果是本地播放&#xff0c;没有解协议这一步骤。 采集数据其实…

Cesium开发环境搭建(二)

由于win7搭建很费事&#xff0c;重新安装了OS&#xff0c;win10的。 记录一下&#xff0c;搭建步骤&#xff1a; 1.下载node.js。 百度搜索即可下载对应的版本。下载cesium。 2.安装node.js。 安装后&#xff0c;输入node -v&#xff0c;显示版本信息&#xff0c;表示安装…

Spring Cloud 微服务集成Sentinel实现服务熔断降级

文章目录 一、前言二、技术思路及方案2.1 实现思路2.2 实现方案2.2.1 nacos动态数据源实现类关系图 三、功能实现3.1 快速集成方案3.1.1 引入依赖3.1.2 服务端熔断降级3.1.3 feign调用降级 四、扩展4.1 SPI机制4.2 自定义Slot实现4.3 基于 Sentinel 实现 Feign 全局异常兜底4.3…

MySQL之查询性能优化(七)

查询性能优化 排序优化 无论如何排序都是一个成本很高的操作&#xff0c;所以从性能角度考虑&#xff0c;应尽可能避免排序或者尽可能避免对大量数据进行排序。前面已经提到了&#xff0c;当不能使用索引生成排序结果的时候&#xff0c;MySQL需要自己进行排序&#xff0c;如果…

【大事件】docker可能无法使用了

今天本想继续学习docker的命令&#xff0c;突然发现官方网站的文档页面打不开了。 难道是被墙了&#xff1f; 我用同事的翻了一下&#xff0c;能进&#xff0c;果然&#xff01; 正好手头的工作告一段落&#xff0c;将代码上传&#xff0c;然后通过jenkins将服务器自动部署到…

Python魔法之旅-魔法方法(20)

目录 一、概述 1、定义 2、作用 二、应用场景 1、构造和析构 2、操作符重载 3、字符串和表示 4、容器管理 5、可调用对象 6、上下文管理 7、属性访问和描述符 8、迭代器和生成器 9、数值类型 10、复制和序列化 11、自定义元类行为 12、自定义类行为 13、类型检…

代码随想录——删除二叉搜索树中的节点(Leetcode450)

题目链接 递归 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

SpringBoot实现图片文件上传和回显的两种方式

目录 一 功能需求 二 上传本地 2.1 实现文件上传的controller层 2.2 图片访问资源映射 二 上传OSS 一 功能需求 实现图片的上传和回显功能其实在业务中是非常常见的&#xff0c;比如需要上传头像&#xff0c;或者交易平台需要上传物品的图片等等&#xff0c;都需要上传和回…

数字后端设计岗位介绍

数字后端设计岗位是数字芯片设计流程中的关键环节&#xff0c;以下是对该岗位的详细介绍&#xff1a; 一、岗位职责 数字后端设计工程师的主要职责包括&#xff1a; 负责将芯片的逻辑设计转化为物理实现&#xff0c;利用EDA工具进行自动布局布线&#xff0c;完成从netlist到…

Linux驱动开发笔记(六)中断子系统及实验

文章目录 前言一、中断子系统框架1. 中断硬件简单描述2. 中断的软件描述 二、GIC v3中断控制器1. GIC v3基本结构1.1 Distributor1.2 Redistributor1.3 ITS1.4 CPU interface 2. 中断类型与特点3. 中断号 三、函数编写3.1 相关API函数3.2 驱动初始化函数3.3 operations函数3.3.…

基于Gdb快速上手调试Redis

写在文章开头 近期很多读者有询问有没有什么简单的办法快速上手调试redis&#xff0c;对此&#xff0c;笔者用到了Linux系统中比较易上手的调试工具GDB&#xff0c;本文将基于一个C语言两数交换的例子演示一下这款工具的使用。 Hi&#xff0c;我是 sharkChili &#xff0c;是个…

【Python深度学习系列】网格搜索神经网络超参数:批量大小和迭代周期数(案例+源码)

这是我的第297篇原创文章。 一、引言 在深度学习中&#xff0c;超参数是指在训练模型时需要手动设置的参数&#xff0c;它们通常不能通过训练数据自动学习得到。超参数的选择对于模型的性能至关重要&#xff0c;因此在进行深度学习实验时&#xff0c;超参数调优通常是一个重要的…

在线Logo背景去除:pixian.ai

文章目录 简介特色 简介 pixian.ai是一款智能图片背景去除工具&#xff0c;进入网页后&#xff0c;会非常醒目地提示你准备【Free】还是【Paid】&#xff0c;这点就非常好&#xff0c;不向有一些网站&#xff0c;主打免费使用&#xff0c;但时不时弹出“免费注册”&#xff0c…

1782java英语陪学记词系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java英语陪学记词系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助采用了java设计&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统采用web模式&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&…

RabbitMQ-工作模式(简单模式工作队列)

文章目录 简单模式&#xff08;simple&#xff09;工作队列&#xff08;work&#xff09;准备工作轮询调度消息确认消息持久性公平分发代码示例 本篇总结 更多相关内容可查看 简单模式&#xff08;simple&#xff09; 通俗概括:生产者-队列-消费者 想详细了解Rabbit的基础或简…

ESD防护SP3232E真+3.0V至+5.5V RS-232收发器

特征 采用3.0V至5.5V电源&#xff0c;符合真正的EIA/TIA-232-F标准 满载时最低 120Kbps 数据速率 1μA 低功耗关断&#xff0c;接收器处于活动状态 &#xff08;SP3222E&#xff09; 可与低至 2.7V 电源的 RS-232 互操作 增强的ESD规格&#xff1a; 15kV人体模型 15kV IEC1000…

软件杯 题目:基于深度学习卷积神经网络的花卉识别 - 深度学习 机器视觉

文章目录 0 前言1 项目背景2 花卉识别的基本原理3 算法实现3.1 预处理3.2 特征提取和选择3.3 分类器设计和决策3.4 卷积神经网络基本原理 4 算法实现4.1 花卉图像数据4.2 模块组成 5 项目执行结果6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基…

计算机毕业设计Spark+Flink+Hive地铁客流量预测 交通大数据 地铁客流量大数据 交通可视化 大数据毕业设计 深度学习 机器学习

项目说明​ ​ 1该项目主要分析通刷卡数据&#xff0c;通过大数据技术来研究地铁客运能力及探索优化服务的方向​ 2主要讲解Flink流处理实时分析部分&#xff0c;离线部分较简单&#xff0c;暂时略过​ ​ 技术架构​ ​项目流程&#xff1a;​ 采用python请求深圳地铁数…