任务:
您有一个未排序的元素列表(在我们的情况下为整数),并且必须在该列表中找到第k个最小的元素。当然,显而易见的想法是按升序对列表进行排序并返回第k个最小元素。这应该在O(N Log N)中完成。
我正在尝试找到使用最大堆的第k个最小元素。据我了解,我需要对Array进行升序排序,并在得到第k个最小元素时返回。如果我正确理解,最好使用最大堆对数组进行升序排序,但是最好使用最小堆来查找第k个最小元素。这是不明白的地方。如何将数组按升序排序并返回第k分钟?我在查找如何使用最大堆的情况下获取第k个最小元素时遇到问题,因为等到数组完全排序后再进行for循环遍历并使其第k个最小就没有意义了。不会使HeapSort O(N log N),因为它将需要另一个for循环来遍历Array。如果我使用Min堆,那将是降序。
Max Heap以这种方式对数组进行升序排序:
产生最大堆:[10,9,8,5,1,8,3,5,5,1]
[9,5,8,5,1,8,3,1,5,10]
[8、5、8、5、1、5、3、1、9、10]
[8、5、5、5、1、1、3、8、9、10]
[5、5、5、3、1、1、8、8、9、10]
[5、3、5、1、1、5、8、8、9、10]
[5、3、1、1、5、5、8、8、9、10]
[3,1,1,5,5,5,8,8,9,10]
[1、3、5、5、5、5、8、8、9、10]
[1、3、5、5、5、5、8、8、9、10]
我不知道如何使第k个最小。我虽然是关于最小堆的,因为最小堆总是索引0,但这是用来制作递减数组吗?
这是我的方法,这是Heapsort。它调用buildHeap,然后进行排序。
//Find kth smallest element-----------------------------------------------------------------------------------------
private int[] findKthSmallestElement(int[] arr, int kthElement) {
buildheap(arr);
System.out.println("Max Heap is made: " + Arrays.toString(arr));
if(kthElement > arr.length){
System.out.println("Number does not exist.");
return arr;
}
else if(kthElement == arr.length){
System.out.println(kthElement + " st/nd/th smallest element number" + " is: " + arr[0]);
return arr;
}
heapSize = arr.length - 1;
for(int i = heapSize; i > 0; i--) {
swapCurrentNodeWithMaxChild(arr,0, i);
heapSize--;
percolateDown(arr, 0,heapSize);
System.out.println(Arrays.toString(arr));
}
return arr;
}
答案 0 :(得分:0)
如果Invoke(null, null)
相对于堆大小k
较小,则从 Max 中检索第k个最小的堆是很长的任务-它需要N
O((N-k)*logN)~O(N*logN)
提取顶部元素的时间。
要解决问题本身-要从未排序的列表中获取最小的k,您不需要完全排序,不需要构建完整堆。
变体1)获取(N-k)
的第一个元素,仅为这k个元素构建 max -堆 。遍历所有其他元素。如果当前项目小于堆顶部,请移除顶部并插入当前项目。在最后,堆顶部包含最小的k。复杂度为k
。
我想如果您现在正在研究堆,则最好使用此变体。
变体2)执行QuickSelect算法(平均复杂度是线性的,但最坏的情况可能会发生)
答案 1 :(得分:0)
我试图在最大堆中找到第k个最小的元素。据我了解,我需要对Array进行升序排序,并在得到第k个最小元素时返回。
否,要在最大堆中找到第k个smalles元素,我们只需要从最大堆中提取n-k
个元素。无需排序。
不会使HeapSort O(N log N),因为它将需要另一个for循环来遍历数组。
我们不需要对数组进行排序,但是请注意,自O(N log N + N) == O(N log N)
答案 2 :(得分:0)
您是否需要显式实现算法或可以使用Java API?
如果可以使用API,则可以通过Arrays.sort()轻松完成。为了简单起见,我省略了测试k public void khtElement(k){
int[] elements = new int[]{10, 9, 8, 5, 1, 8, 3, 5, 5, 1};
Arrays.sort(elements);
System.out.println(elements[k-1]);
}