簡體   English   中英

查找k-最小元素(Java代碼)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM