[英]Find k - smallest element (Java code)
我想解決以下問題:給定n個元素的未排序數組,找到前k個最小的元素。 為此,我想構建一個最大大小為k的最大堆(從數組的最后k個元素開始),然后掃描數組中的其余元素。 如果找到比根元素小的元素,則交換兩個元素,然后對堆進行堆化。 此解決方案應在O(nlogk)時間和適當的時間工作。 但是我無法解決它(我的索引超出了綁定的異常)。 我嘗試調試它,但看不到我的錯誤在哪里。 這是我的代碼:
public class KSmallest {
private static int[] a;
private static int n;
public static void buildheap(int []a){
n=a.length-1;
for(int i=n;i>=0;i--){
maxheap(a,i);
}
for (int i = n-1; i >= 0; i--) {
if(a[i]<a[start]){
exchange(i, 0);
maxheap(a, 0);
}
}
}
public static void exchange(int i, int j){
int t=a[i];
a[i]=a[j];
a[j]=t;
}
public static void sort(int []a0){
a=a0;
for(int i=n; i>0; i--){
exchange(0, i);
n=n-1;
maxheap(a, 0);
}
}
public static void main(String[] args) {
int []a1={4,1,3,2,7, 2, 1, 4};
int start = a1.length-k;
for(int i=start;i<a1.length;i++){
System.out.print(a1[i] + " ");
}
System.out.println();
//sort(a1);
for(int i=start;i<a1.length;i++){
System.out.print(a1[i] + " ");
}
}
}
我在這方面苦苦掙扎了兩天,希望有人能幫上忙。
我知道這是一項學習練習,請隨時忽略此答案。 但是,如果有人在現實世界中需要這樣做,則可以使用此n * log(n)解決方案。
public static Collection<Integer> findKSmallest(Collection<Integer> data, int k) {
assert k > 0;
assert k <= data.size();
ArrayList<Integer> dataAsList = new ArrayList<Integer>(data);
Collections.sort(dataAsList);
return dataAsList.subList(0, k);
}
首先要注意的是變量名稱,它們的含義不是很明顯...'a','a0','i','j','k','n','t'以及可變的靜態變量始終是一個噩夢。
無論如何,我運行了代碼,並在exchange()方法中得到了NullPointerException。
發生的情況是buildheap()方法有一個名為'a'的參數,該參數與類變量使用的名稱相同,因此,當將'a'傳遞給maxheap()然后將exhange()傳遞時,它將傳遞類變量而不是參數。
嘗試將這一行添加為buildheap()方法的第一行:
KSmallest.a = a;
編輯我不確定這是否會真正起作用,但是會阻止NPE。
為所有變量使用有意義的名稱(例如與“ left”,“ right”,“ largest”等一起使用)將很有幫助,另外一些字符不會浪費樹木!
也嘗試避免可變的靜態變量。 通過使用“ final”關鍵字將它們保留為常量,並且-按照慣例-將它們全部設置為大寫。 或者使用實例變量代替並刪除static關鍵字,這就是更多的OOP范例。
無論如何,祝你好運! :)
編寫堆數據結構是一個好習慣。 我正在使用優先級隊列,該優先級隊列在Java中很容易就可以使用。 對於這個問題,我需要一個最大堆,所以我正在使用一個比較器來創建一個最大堆。
public class KLowestElements {
/*comparator to create max heap*/
static class MaxHeapComparator implements Comparator<Integer> {
@Override
public int compare(Integer a, Integer b) {
return b.compareTo(a);
}
}
public static void main(String[] args) {
//sample input
int[] input = { 11, 2, 23, 34, 5};
// heap size
int k = 3;
MaxHeapComparator maxHeapComparator = new MaxHeapComparator();
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(k,
maxHeapComparator);
//Loop Invariant: If heap size is k, compare top element with next
//element in the array. If element is smaller than the top element,
//remove the top integer and insert element from array.
for (int i = 0; i < input.length; i++) {
if (maxHeap.size() < k) {
maxHeap.add(input[i]);
} else if (maxHeap.peek() > input[i]) {
maxHeap.remove();
maxHeap.add(input[i]);
}
}
//print values
for (int i : maxHeap) {
System.out.print(i + " ");
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.