news 2026/8/26 17:26:35

Java 第k个最小元素(K’th Smallest Element)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java 第k个最小元素(K’th Smallest Element)

目录

【朴素方法】使用排序——时间复杂度为 O(n log(n)),空间复杂度为 O(1)

【预期方法】使用最大堆 - 时间复杂度为 O(n * log(k)),空间复杂度为 O(k)

【替代方案 1】使用快速选择

【替代方案 2】使用计数排序


如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

给定一个整数数组arr[]和元素个数k,求数组中第 k 小的元素。
注意:k 始终小于数组的大小。

例如:

输入:arr[] = [10, 5, 4, 3, 48, 6, 2, 33, 53, 10], k = 4

输出:5

说明:给定数组中第四小的元素是 5。

输入:arr[] = [7, 10, 4, 3, 20, 15], k = 3

输出:7

说明:给定数组中第三小的元素是 7。

【朴素方法】使用排序——时间复杂度为 O(n log(n)),空间复杂度为 O(1)

其思路是对给定的数组进行排序,并返回索引 k - 1 处的元素。

import java.util.Arrays;

class GFG {

static int kthSmallest(int[] arr, int k) {

// Sort the given array
Arrays.sort(arr);

// Return k'th element in the sorted array
return arr[k - 1];
}

public static void main(String[] args) {
int[] arr = {10, 5, 4, 3, 48, 6, 2, 33, 53, 10};
int k = 4;

System.out.println(kthSmallest(arr, k));
}
}

输出
5

【预期方法】使用最大堆 - 时间复杂度为 O(n * log(k)),空间复杂度为 O(k)

其思路是在遍历数组的过程中维护一个大小为 k 的最大堆。该堆始终包含目前为止遇到的 k 个最小元素。如果堆的大小超过 k,则移除最大的元素。最终,堆中只保留 k 个最小元素。

import java.util.PriorityQueue;
import java.util.Collections;

class GFG {

static int kthSmallest(int[] arr, int k)
{
// Create a max heap
PriorityQueue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());

// Iterate through the array elements
for (int val : arr)
{
// Push the current element onto the max heap
pq.add(val);

// If the size of the max heap exceeds k,
// remove the largest element
if (pq.size() > k)
pq.poll();
}

// Return the kth smallest element (top of the max heap)
return pq.peek();
}

public static void main(String[] args)
{
int[] arr = {10, 5, 4, 3, 48, 6, 2, 33, 53, 10};
int k = 4;

System.out.println(kthSmallest(arr, k));
}
}

输出
5

【替代方案 1】使用快速选择

主要思路是利用快速选择(QuickSelect)函数找到第 k 大元素。具体做法是:选择一个基准元素,然后将数组分割成多个部分,使得大于基准元素的元素位于左侧,小于基准元素的元素位于右侧。如果基准元素最终位于索引 k-1 处,则该元素即为第 k 大元素。否则,我们递归地仅在包含第 k 大元素的左侧或右侧部分进行搜索。

class GFG {

static int partition(int[] arr, int left, int right) {

// Choose the last element as pivot
int pivot = arr[right];
int i = left;

// Traverse the array and move elements <= pivot to the left
for(int j = left; j < right; j++) {
if(arr[j] <= pivot) {

// Swap current element with element at i
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
}
}

// Place the pivot in its correct position
int temp = arr[i];
arr[i] = arr[right];
arr[right] = temp;
return i;
}

static int quickSelect(int[] arr, int left, int right, int k) {

if(left <= right) {

// Partition around pivot
int pivotIndex = partition(arr, left, right);

// Found k-th smallest
if(pivotIndex == k) return arr[pivotIndex];

else if(pivotIndex > k)
return quickSelect(arr, left, pivotIndex - 1, k);

else return quickSelect(arr, pivotIndex + 1, right, k);
}
return -1;
}

static int kthSmallest(int[] arr, int k) {
return quickSelect(arr, 0, arr.length-1, k-1);
}

public static void main(String[] args) {
int[] arr = {10,5,4,3,48,6,2,33,53,10};
int k = 4;
System.out.println(kthSmallest(arr, k));
}
}

输出
5

时间复杂度: 最坏情况下为O(n² ),但平均时间为 O(n log n),且性能优于基于优先级队列的算法。

辅助空间: 最坏情况下递归调用栈为 O(n)。平均而言:O(log n)。

【替代方案 2】使用计数排序

主要思路是利用计数排序的频率计数来跟踪有多少元素小于或等于每个值,然后直接从这些累积计数中识别出第 K 小的元素,而无需对数组进行完全排序。

注意:这种方法在元素范围较小时特别有效,因为我们声明的数组大小为最大元素个数。如果元素范围非常大,计数排序方法可能并非最有效的选择。

class GFG {

static int kthSmallest(int[] arr, int k) {

// First, find the maximum element in the array
int maxElement = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > maxElement) {
maxElement = arr[i];
}
}

// Create an array to store the frequency of each element
int[] freq = new int[maxElement + 1];
for (int i = 0; i < arr.length; i++) {
freq[arr[i]]++;
}

// Keep track of the cumulative frequency of elements
int count = 0;
for (int i = 0; i <= maxElement; i++) {
if (freq[i] != 0) {
count += freq[i];
if (count >= k) {
// If we have seen k or more elements,
// return the current element
return i;
}
}
}
return -1;
}

public static void main(String[] args) {
int[] arr = {10, 5, 4, 3, 48, 6, 2, 33, 53, 10};
int k = 4;
System.out.println(kthSmallest(arr, k));
}
}

输出
5

时间复杂度: O(n + maxElement),其中 maxElement 为数组中的最大元素。

辅助空间: O(maxElement)。

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/26 17:25:52

毕得医药(688073.SH)深度研究报告

摘要本报告围绕毕得医药&#xff08;688073.SH&#xff09;展开深度分析&#xff0c;从投资要点、公司概况、行业格局、财务表现、核心竞争力、未来增长点及风险提示等维度进行系统梳理。公司聚焦药物分子砌块和科学试剂领域&#xff0c;凭借产品品类丰富、仓储物流高效和客户结…

作者头像 李华
网站建设 2026/8/26 17:22:17

Large Language Models are Highly Aligned with Human Ratings of Emotional Stimuli

文章总结与翻译 一、主要内容 该研究聚焦大型语言模型(LLMs)与人类对情绪刺激评分的一致性,旨在明确LLMs对情绪刺激的解读方式,为其在需情绪智力的场景(如助手、治疗师、教师)应用提供依据。 1. 研究背景 情绪对人类行为和认知影响重大,是心理学研究百年重点,而当前…

作者头像 李华
网站建设 2026/8/26 17:21:44

GTool: Graph Enhanced Tool Planning with Large Language Model

GTool:基于图增强的大语言模型工具规划方法(文章总结与翻译) 一、文章主要内容总结 1. 研究背景与问题 当前大语言模型(LLMs)在自然语言处理任务中表现突出,但在数值计算、复杂问题求解等场景中依赖外部工具(如API、算法)。工具规划作为LLMs与工具交互的核心能力,需…

作者头像 李华
网站建设 2026/8/26 17:12:36

人工智能+软件”新范式:从卖工具到卖成果的商业模式革命

# “人工智能软件”新范式&#xff1a;从卖工具到卖成果的商业模式革命2026年6月&#xff0c;国家工业信息安全发展研究中心在第四届软件创新发展大会上发布《“人工智能软件”发展洞察》报告&#xff0c;明确提出一个关键判断&#xff1a;**AI时代软件价值的底层逻辑正在发生根…

作者头像 李华
网站建设 2026/8/26 17:10:17

AI生成的减肥计划,到底能不能相信?专家分析

社交平台之上, 众多的网友纷纷分享, 由AI大模型所生成的减肥计划, 网络截图。近段时间, AI减肥变得相当流行, 把自己当下的体重以及目标体重输入到AI大模型, 大模型会生成减肥的计划, 含括食谱、运动方案等内容, 用户依照去做就行。在社交平台之上, 有不少网友, 去分享自身的 A…

作者头像 李华