求数组中的第k小元素

news/2024/10/30 21:31:08/

文章目录

  • 第k小的元素
    • 🔒题目
    • 💡分析
    • 🔑题解
      • 🍃不去重版
      • 🍃去重版

第k小的元素

🔒题目

image-20230220145800496

题目来源:3533. 查找第K小数 - AcWing题库

💡分析

  • 不去重版思路
  • 去重版思路

🔑题解

🍃不去重版

只能对于非重复元素的数组才有效,对于出现了重复元素的数组并不能得到正确答案,所以还需要改进

  • 方式一:采用快速排序策略,核心思想**分治+递归**

    时间复杂度:O(nlogn)O(nlogn)O(nlogn),n为数组中元素的个数

    import java.util.Scanner;/*** @author ghp* @title 求第k小的元素(不去重版)* @description 通过快速排序策略得到数组中第k小的数*/
    public class Main {public static void main(String[] args) {// 接收输入Scanner sc = new Scanner(System.in);int n = sc.nextInt();int[] arr = new int[n];for (int i = 0; i < n; i++) {arr[i] = sc.nextInt();}int k = sc.nextInt(); // 第k小// 通过快速排序查找到第k小的数int result = findKthByQuickSort(arr, 0, arr.length - 1, k);// 输出第k小的数System.out.println(result);}/*** 通过快速排序查找第k小的数* @param arr 待查找的数组* @param left 待查找数组的左侧索引* @param right 待查找数组的右侧索引* @param k 第k小* @return 返回第k小的数,arr中不含有则返回-1*/private static int findKthByQuickSort(int[] arr, int left, int right, int k) {if(left>right) {// 未找到要查找的数,返回-1,递归终止return -1;}// 获取主元int pivot = partition(arr, left, right);int result; // 第k小的元素if (k == pivot - left + 1) {// 第k小的元素就是当前子数组的主元result = arr[pivot];} else if (k < pivot - left + 1) {// 第k小的元素在主元左侧result = findKthByQuickSort(arr, left, pivot - 1, k);} else {// 第k小的元素在主元右侧result = findKthByQuickSort(arr, pivot + 1, right, k - (pivot - left + 1));}// 返回第k小的数return result;}/*** 根据主元划分数组(左侧子数组恒小于等于主元,右侧子数组恒)* @param arr 待划分的数组* @param left 待划分数组的左侧索引* @param right 待划分数组的右侧索引* @return 返回本次用于划分数组的主元*/private static int partition(int[] arr, int left, int right) {int pivot = arr[right]; // 主元int i = left - 1; // 左右子数组的分界点// 遍历arr,然后根据主元划分出两个子数组for (int j = left; j <= right - 1; j++) {// 将比主元小的数组放到i+1的左侧(注意: i+1也比主元小)if (arr[j] < pivot) {int tmp = arr[i + 1];arr[i + 1] = arr[j];arr[j] = tmp;i++;}}// 将主元放到分界点int temp = arr[i + 1];arr[i + 1] = arr[right];arr[right] = temp;// 返回主元索引return i + 1;}
    }
    

    image-20230220150258388

  • 方式二:调用Java的API,主要思路,先去重,然后通过Arrays.sort()方法进行排序

    时间复杂度:O(nlogn)O(nlogn)O(nlogn),n为数组中元素的个数

    import java.util.Arrays;
    import java.util.Scanner;/*** @author ghp* @title 求第k小的元素* @description*/
    public class Main {public static void main(String[] args) {// 接收输入Scanner sc = new Scanner(System.in);int n = sc.nextInt();int[] arr = new int[n];for (int i = 0; i < n; i++) {arr[i] = sc.nextInt();}int k = sc.nextInt(); // 第k小// 去除重复元素Arrays.sort(arr);// 输出第k小的数System.out.println(arr[k-1]);}
    }
    

    image-20230220164708025

🍃去重版

  • 方式一:利用Set集合的特性

    核心思想是利用Set集合的特性

    1. Set集合中的元素不可重复
    2. Set集合中的元素默认是升序排序的

    时间复杂度:O(n)O(n)O(n)

    import java.util.Arrays;
    import java.util.HashSet;
    import java.util.Scanner;
    import java.util.Set;/*** @author ghp* @title 求第k小的元素* @description*/
    public class Main {public static void main(String[] args) {// 接收输入Scanner sc = new Scanner(System.in);int n = sc.nextInt();int[] arr = new int[n];for (int i = 0; i < n; i++) {arr[i] = sc.nextInt();}int k = sc.nextInt(); // 第k小// 去除重复元素int[] nums = Arrays.stream(removeRepeat(arr)).mapToInt(Integer::valueOf).toArray();// 输出第k小的数System.out.println(arr[k-1]);}/*** 去除重复元素* @param arr* @return*/private static Integer[] removeRepeat(int[] arr) {Set<Integer> set = new HashSet<>();for (int i = 0; i < arr.length; i++) {set.add(arr[i]);}return set.toArray(new Integer[set.size()]);}
    }
    

image-20230220163947048


http://www.ppmy.cn/news/26874.html

相关文章

罗技LogitechFlow技术--惊艳的多电脑切换体验

作者&#xff1a;Eason_LYC 悲观者预言失败&#xff0c;十言九中。 乐观者创造奇迹&#xff0c;一次即可。 一个人的价值&#xff0c;在于他所拥有的。所以可以不学无术&#xff0c;但不能一无所有&#xff01; 技术领域&#xff1a;WEB安全、网络攻防 关注WEB安全、网络攻防。…

【ESP 保姆级教程】玩转巴法云篇② ——MQTT设备云,MQTT协议下的数据通信

忘记过去,超越自己 ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2023-02-21 ❤️❤️ 本篇更新记录 2023-02-21 ❤️🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请…

算法分析详解

自古老的公元前1世纪开始&#xff0c;《周髀算经》就作为中国最古老的天文学和数学著作。 《周髀算经》采用最简便可行的方法确定天文历法&#xff0c;揭示日月星辰的运行规律&#xff0c;包括四季更替&#xff0c;气候变化&#xff0c;南北有极&#xff0c;昼夜相推的道理。为…

【蓝桥杯集训·每日一题】AcWing 1497. 树的遍历

文章目录一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解三、知识风暴递归一、题目 1、原题链接 1497. 树的遍历 2、题目描述 一个二叉树&#xff0c;树中每个节点的权值互不相同。 现在给出它的后序遍历和中序遍历&#xff0c;请你输出它的 …

C语言【柔性数组】

柔性数组&#x1fac5;什么是柔性数组&#x1fac5;柔性数组的使用&#x1fac5;柔性数组的优势&#x1fac5;什么是柔性数组 也许你从来没有听说过柔性数组&#xff08;flexible array&#xff09;这个概念&#xff0c;但是它确实是存在的。 C99 中&#xff0c;结构中的最后一…

【JavaScript速成之路】JavaScript数据类型转换

&#x1f4c3;个人主页&#xff1a;「小杨」的csdn博客 &#x1f525;系列专栏&#xff1a;【JavaScript速成之路】 &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; 文章目录前言数据类型转换1&#xff0c;转换为字符串型1.1&#xff0c;利用“”拼接转换成…

【kubernetes】使用crictl对k8s节点进行调试

crictl 是 CRI 兼容的容器运行时命令行接口,可以使用它来检查和调试 Kubernetes 节点上的容器运行时和应用程序。 可以Github上下载最新的发布版本: https://github.com/kubernetes-sigs/cri-tools/releases 包名大小发布日期

【Linux】进程状态的理解

✍作者&#xff1a;阿润菜菜 &#x1f4d6;专栏&#xff1a;Liunx系统编程 本文目录概述两个先行概念我们为啥创建进程Linux下的进程状态1. R 运行状态2.S 休眠状态 --- 可中断休眠状态3. D 磁盘休眠状态 ---不可中断休眠4.T 暂停状态 &#xff08;t 追踪暂停状态&#xff09;5…