Acwing 786.第K个数

news2024/10/6 12:19:07

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;
}

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

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

相关文章

网络通讯协议UDP转发TCP工具_UdpToTcpRelay

网络通讯协议UDP转发TCP工具_UdpToTcpRelay 本程序旨在提供一个灵活的、可配置的服务&#xff0c;它处理特定的UDP端口以接收命令&#xff0c;然后将这些命令转换为TCP命令并通过网络发送到指定的TCP服务器【TCP支持十六进制和ASCII】。 此设计特别适用于需要远程控制或自动化…

百度/迅雷/夸克,网盘免费加速,已破!

哈喽&#xff0c;各位小伙伴们好&#xff0c;我是给大家带来各类黑科技与前沿资讯的小武。 之前给大家安利了百度网盘及迅雷的加速方法&#xff0c;详细方法及获取参考之前文章&#xff1a; 刚刚&#xff01;度盘、某雷已破&#xff01;速度50M/s&#xff01; 本次主要介绍夸…

Day23 自定义对话框服务

​本章节实现了,自定义对话框服务的功能 当现有的对话框服务无法满足特定需求时,我们可以采用自定义对话框的解决方案,以更好地满足一些特殊需求。 一.自定义对话框主机服务步骤 在Models 文件夹中,再建立一个 IDialogHostService 接口类,继承自 IDialogService 对话框服…

[个人总结]-java常用方法

1.获取项目根路径 user.dir是一个系统属性&#xff0c;表示用户当前的工作目录&#xff0c;大多数情况下&#xff0c;用户的当前工作目录就是java项目的根目录&#xff08;src文件的同级路径&#xff09; System.getProperty("user.dir") 结果&#xff1a;D:\code…

什么是IDE?– 集成开发环境

IDE &#xff08;集成开发环境&#xff09;是将常用的开发人员工具组合到紧凑的 GUI&#xff08;图形用户界面&#xff09;应用程序中的软件。它是代码编辑器、代码编译器和代码调试器等工具与集成终端的组合。 为什么 IDE 很重要&#xff1f; 人们当然不需要 IDE来编码或开发…

【动手学深度学习】softmax回归从零开始实现的研究详情

目录 &#x1f30a;1. 研究目的 &#x1f30a;2. 研究准备 &#x1f30a;3. 研究内容 &#x1f30d;3.1 softmax回归的从零开始实现 &#x1f30d;3.2 基础练习 &#x1f30a;4. 研究体会 &#x1f30a;1. 研究目的 理解softmax回归的原理和基本实现方式&#xff1b;学习…

Python SQLAlchemy库详解

大家好&#xff0c;在Python生态系统中&#xff0c;SQLAlchemy库是一个强大的工具&#xff0c;为开发人员提供了便捷的方式来处理与数据库的交互。无论是开发一个小型的Web应用程序&#xff0c;还是构建一个大型的企业级系统&#xff0c;SQLAlchemy都能满足你的需求&#xff0c…

hid.dll丢失怎么办?hid.dll丢失多种解决方法详解

hid.dll&#xff0c;即Human Interface Device (HID) Dynamic Link Library&#xff0c;是Windows操作系统中用于管理人机交互设备&#xff08;如键盘、鼠标、游戏控制器等&#xff09;的动态链接库文件。它负责处理这些设备的输入和输出&#xff0c;确保设备与系统之间的通信顺…

SpringBoot+Vue在线考试答题系统【附:资料➕文档】

前言&#xff1a;我是源码分享交流Coding&#xff0c;专注JavaVue领域&#xff0c;专业提供程序设计开发、源码分享、 技术指导讲解、各类项目免费分享&#xff0c;定制和毕业设计服务&#xff01; 免费获取方式--->>文章末尾处&#xff01; 项目介绍016&#xff1a; 本…

windows10子系统wsl ubuntu22.04下GN/ninja环境搭建

打开windows10子系统 ubuntu22.04 ubuntu22.04: 首先需要 安装ninja $sudo apt install ninja-build $ ninja --version 1.10.0 安装clang $sudo apt install clang $clang --version Ubuntu clang version 14.0.0-1ubuntu1.1安装gn Github: https://github.com/timniederh…

如何在npm上发布自己的包

如何在npm上发布自己的包 npm创建自己的包 一、一个简单的创建 1、创建npm账号 官网&#xff1a;https://www.npmjs.com/创建账号入口&#xff1a;https://www.npmjs.com/signup 注意&#xff1a;需要进入邮箱验证 2、创建目录及初始化 $ mkdir ufrontend-test $ cd ufron…

LLM主流开源代表模型

LLM主流开源大模型介绍 1 LLM主流大模型类别 随着ChatGPT迅速火爆&#xff0c;引发了大模型的时代变革&#xff0c;国内外各大公司也快速跟进生成式AI市场&#xff0c;近百款大模型发布及应用。 目前&#xff0c;市面上已经开源了各种类型的大语言模型&#xff0c;本章节我们…

用idea将java文件打成jar包

一、用idea将java文件打成jar包 1、在idea上选择file—Project Structure 2、Artifacts —点–JAR—From modules with dependencies 3、选择要打包的java文件 4、Build — Build Artifacts 5、找到刚才添加的Artifacts直接Build 6、生成jar包文件

tomcat服务器之maxHttpHeaderSize

背景&#xff1a;在OA流程表单中&#xff0c;填写了200条数据&#xff0c;一提交&#xff0c;秒报400错误&#xff0c;且请求没有打到后端中&#xff08;无报错日志&#xff09;&#xff0c;一开始以为是谷歌浏览器的问题&#xff0c;可百度上关于这个错误的解决方案都是清除缓…

Renesas MCU之FreeRTOS的应用

目录 概述 1 FSP配置FreeRTOS 1.1 软件版本信息 1.2 配置FreeRTOS 2 FreeRTOS的Task 2.1 FSP下的项目结构 2.2 Task代码 2.2.1 Task测试案例配置 2.2.2 测试代码实现 3 自定义Task 3.1 编写代码 3.2 测试函数 4 测试 4.1 Task断点测试 4.2 板卡运行测试 概述 …

Spring boot 集成mybatis-plus

Spring boot 集成mybatis-plus 背景 Spring boot集成mybatis后&#xff0c;我们可以使用mybatis来操作数据。然后&#xff0c;我们还是需要写许多重复的代码和sql语句&#xff0c;比如增删改查。这时候&#xff0c;我们就可以使用 mybatis-plus了&#xff0c;它可以极大解放我…

CC++内存管理【new和delete操作符的详细分析】【常见面试题】

C/C内存管理 1.C/C内存分布 我们先来看一段代码&#xff0c;来了解一下C/C中的数据内存分布。 # include <stdlib.h>int globalVar 1; static int staticGlobalVar 1; // 比globalVar还要先销毁,同一个文件下后定义的先析构 // 全局变量存在 数据段&#xff08;静态…

opencv进阶 ——(十三)基于三角剖分实现换脸

换脸的关键在于人脸对齐&#xff0c;人脸对齐主要包括以下几点&#xff1a; 1、人脸可能存在一定的角度&#xff0c;因此需要先将倾斜方向进行对齐 2、大小对齐&#xff0c;将模板人脸的大小缩放到同一大小 3、要想有好的效果&#xff0c;关键点选取很重要 4、人脸对齐后&a…

前端自测 - 那些经典的bug

前言 我一直坚持的一个观点&#xff0c;就是不以bug数论成败&#xff0c;但是这个需要加一个前提&#xff0c;就是不能出现那些低级的bug&#xff0c;更不能反复的出现。 由此整理了一系列我认为比较经典常见的前端bug&#xff0c;都是在项目中多次遇到过的&#xff0c;用于前…

14. WinCC 无法打开画面编辑器Graphis Designer,且提示X值坐标过大,Y值坐标过大

wincc双击画面一直显示在这个界面&#xff0c;并且这个窗口背后还有小窗口。 直接回到桌面主界面下&#xff0c;点一下这个窗口&#xff0c;窗口消失&#xff0c;点击任务栏的wincc图标会弹窗&#xff0c;显示X坐标值过大&#xff0c;Y坐标值过大。将这些窗口都点击确定之后就…