問題を解決するためTOPKの方法

問題のTOPKの説明:

Nは、kの最大数は、これは古典的な問題である場所を見つけるために数字を指定TOPK

解決策1:グローバル順序

  • 数nが最大除去Kソート完全に、即ち、所望の結果であります
  • コード:
    public int[] topK(int[] array, int k) {
        Arrays.sort(array);
        return Arrays.copyOfRange(array, array.length - k, array.length);
    }
  • 時間計算量はO(N * logN個)

対処方法2:ローカルソート

  • 実際には、それは単に事前K、すべての要素がソートされていることをあなたがソート停止することができ、それを整理するための最大値は不要であり、k値は、必要の結果であります
  • コード
    public int[] topK(int[] array, int k) {
        for(int i = 0; i < k; i++) {
            for(int j = array.length - 1; j > 0; j--) {
                if(array[j] > array[j - 1]) {
                    int tmp = array[j];
                    array[j] = array[j - 1];
                    array[j - 1] = tmp;
                }
            }
        }
    }
  • 時間計算量はO(K * N)であります

解決策3:ヒープ

  • 次いで小さなヒープサイズkの構築、ヒープにK最初の要素、および残りの要素を横断する、横断の終了後、スタックの一番上のスタック要素の上部場合よりも大きく、要素が交換され、得られたヒープ値は、最初のk個の最大の値であります
  • コード
    public Integer[] topK(int[] array, int k) {
        PriorityQueue<Integer> queue = new PriorityQueue<>();
        for(int i = 0; i < k; i++) {
            queue.add(array[i]);
        }
        for(int i = k; i < array.length; i++) {
            if(array[i] > queue.peek()) {
                queue.poll();
                queue.add(array[i]);
            }
        }
        return (Integer[])queue.toArray();
    }
  • 時間の複雑さ:O(N * logK)

解決策4:ランダムな選択

  • 彼は彼の右少し置いより使いマイナスガバナンスのアイデア、彼の左のフラグ要素よりも大きな要素フラグを開発し、
  • 左側の旗の要素の大規模な範囲の前にk個のk個の命令をより添字インデックス以上のフラグ、およびその後、彼は最初のステップに残っている場合は、kの値の下でラベルされたセクションを見つけるまで繰り返されます
  • K-indexの値フラグ添字インデックスはちょうど彼の右少し説明間隔比kに添字を見つけるための最初のステップを繰り返している場合
  • k値が大きいが、この手順を行う見つけ、その左にあるすべての要素は、最初のkの最大値であり、
  • コード:

    public int[] topK5(int[] array, int k) {
        int left = 0;
        int right = array.length - 1;
        //因为数组下标是以0开始的,因此第k个的小标为k - 1,因此传入的为k - 1
        int flag = RS(array, left, right, k - 1);
        //返回值flag为第k个最大值的下标,因此需要前k个最大的值时,拷贝数组的范围是[0, flag + 1)
        return Arrays.copyOfRange(array, 0, flag + 1));
    }
    
    private int RS(int[] array, int left, int right, int k) {
        if (left >= right) {
            return left;
        }
    
        int index = partition(array, left, right);
        int temp = index - left;
    
        if(temp >= k) {
            return RS(array, left, index - 1, k);
        } else {
            return RS(array, index + 1, right, k - index);
        }
    }
    
    private int partition(int[] array, int left, int right) {
        int tmp = array[left];
        int l = left;
        int r = right;
    
        while(l < r) {
            while(l < r && array[r] <= tmp) {
                r--;
            }
            array[l] = array[r];
            while(l < r && array[l] >= tmp) {
                l++;
            }
            array[r] = array[l];
        }
        array[l] = tmp;
        return l;
    }
  • 時間の複雑さ:O(N)

おすすめ

転載: blog.51cto.com/14233687/2471821
おすすめ