Top K問題——Parition算法

Top K問題概述

  • 在非海量數(shù)據(jù)的情況下,Top K問題的首推解法就是快排中的Parition算法。不僅平均時間復(fù)雜度優(yōu)越,可以達(dá)到O(n),并且相比于基于堆的算法(包括:min_heapify、build_heap、insert等一系列過程),編碼更簡潔。
  • 在海量數(shù)據(jù)的情況下,還是老老實(shí)實(shí)選擇基于堆的這一數(shù)據(jù)結(jié)構(gòu)的算法吧。時間復(fù)雜度為O(nlogk)。并且大多數(shù)高級編程語言中都應(yīng)該內(nèi)置了基于堆的API,所以編寫起來也沒有那么麻煩,例如JDK中的:java.util.PriorityQueue<>。

基于Partition算法

  • 選擇一個Position(稱為基準(zhǔn)),基于該算法的Top k算法,非常受Position好壞的影響,所謂的壞,有可能使時間復(fù)雜度達(dá)到O(n*n)。
  • 然后利用Partition算法進(jìn)行劃分,如果Partition得到的p小于K,則繼續(xù)劃分p的右邊,如果p大于K,則繼續(xù)劃分p的左邊,如果p等于K,則算法結(jié)束。

Code

import java.util.Scanner;

/**
 * 利用快排中parition算法,找到第k大數(shù),平均時間復(fù)雜度為O(n)
 */
public class FindK
{
    //測試
    public static void main(String[] args)
    {
        int k = 0;
        Scanner scanner = new Scanner(System.in);
        k = scanner.nextInt();
        scanner.close();

        int[] a = {2, 6, 3, 10, 45, 12, 5, 6, 5, 6};
        if (k >= 0 && k < a.length) {
            findMaxK(a, 0, a.length - 1, k);
            System.out.println("第"+ (k+1) +"大數(shù)為:" + a[k]);
        } else
            System.out.println("are you kidding me ?");
    }
    
    //遞歸劃分
    private static void findMaxK(int[] a, int low, int high, int k)
    {
        int p = partition(a, low, high);
        if (p == k)
        {
            return;
        }
        if (p < k)
        {
            findMaxK(a, p + 1, high, k);
        }else{
            findMaxK(a, low, p - 1, k);
        }
    }

    //核心算法:劃分
    private static int partition(int[] a, int low, int high)
    {
        int position = a[high];
        int i = low - 1;
        for (int j = low; j < high; ++j)
        {
            if (a[j] <= position)
            {
                ++i;
                exchange(a, i, j);
            }
        }
        exchange(a, i + 1, high);
        return i + 1;
    }

    static void exchange(int[] a, int i, int j)
    {
        int temp = a[j];
        a[j] = a[i];
        a[i] = temp;
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問題, 分享了一些自己做題目的經(jīng)驗(yàn)。 張土汪:刷leetcod...
    土汪閱讀 12,890評論 0 33
  • 今天下午,治療完患者后,臨下班前還有一段空余時間,彬哥說他扭傷的腳踝有些腫,一直這么拖著也不是辦法,想波波師兄看看...
    立新七針李麗霞閱讀 354評論 0 0
  • 不要再無所事事了,趕緊把身邊的事處理完,然后專心升本,考完減肥,加油
    西瓜吃橘子閱讀 192評論 0 0
  • 我是付費(fèi)閱讀擁護(hù)者,如果你想體驗(yàn)付費(fèi)閱讀的感覺,不妨滑到最后贊賞一筆再滑回來繼續(xù)讀。 寫一些東西,在我自己看來算是...
    漁夫簡想閱讀 432評論 2 4
  • 關(guān)于愛情,你想說些什么? 我無話可說。 你用力撕扯那早已死去的枝椏,希望能夠?qū)⑺鼡u醒,但只能讓它腐朽得更快。 你狂...
    可汗閱讀 129評論 0 0

友情鏈接更多精彩內(nèi)容