java - 优化程序以查找数组中的第 k 个最小元素(Java,预期时间复杂度 O(n))
问题描述
问:给定一个数组 arr[] 和一个数 K,其中 K 小于数组的大小,任务是找到给定数组中第 K 个最小的元素。假设所有数组元素都是不同的。
我已经浏览了与这个问题相关的所有帖子,但没有一个能帮助我解决时间复杂度问题。我是编码新手,很难优化我的解决方案。
预期时间复杂度为 O(n)
这是我的时间复杂度为 O(nlogn) 的函数:
public static void smallestk(int arr[],int k)
{
Arrays.sort(arr);
System.out.println(arr[k-1]);
}
输出是正确的,但我想将我的代码从 O(nlogn) 优化到 O(n)
解决方案
这个问题的最佳情况是 O(nlogk),我们可以使用最大或最小堆数据结构来解决这个问题。如果 k 很小,这将接近 O(n)。这个想法是我们不必对整个数组进行排序,而是取一个大小为 k 的堆,并且总是在堆中存在的 k 个元素中排序。
- O(n) 用于遍历数组
O(logk) 用于使用堆排序对 k 个元素进行排序。
public Integer getKthEle(Integer[] numbers, int k) {
PriorityQueue<Integer> maxHeap = new PriorityQueue(k, new Comparator<Integer>() { public int compare(Integer a, Integer b) { return b-a; } } ); for(int i=0;i<k;i++) { maxHeap.offer(numbers[i]); } // maintain the size k by adding to the queue if the next element is smaller than the head of the queue; remove from the head of the queue which is the largest element in the queue for(int i=k;i<numbers.length;i++) { if(numbers[i] < maxHeap.peek()) { maxHeap.offer(numbers[i]); maxHeap.poll(); } } return maxHeap.peek();
}
推荐阅读
- java - JOOQ 中的 CASE 表达式
- swift - 如何获得Double小数点后的第一个数字?
- ios - 如何使用自定义科尔多瓦插件从 ionic1 到本机 ios swift 进行通信
- java - 如何使用 Oracle AQ 和 java 监视/监听 oracle 表的任何插入/更新
- database - 这个简单的联系表格最好的关系数据库结构是什么?
- kubernetes - Kubernetes 自动回滚
- r - 在 R 中,如何在使用 par() 函数绘图时附加行?
- database - 经常性罚款支付的数据库设计
- ios - 纵向时未在主视图控制器中调用 SplitViewController 和 viewWillAppear 的问题
- python - 如何使用pandas python为excel中的最后一行设置颜色