對於這個問題, 最容易想到的辦法就是給陣列排個序, 如果使用快速排序,時間複雜度是o(nlogn), 但事實上我們只需要尋找這k個數,排序的方法顯然做了多餘的事情。
那麼,能不能在這個基礎上優化一下呢?
我們知道,快速排序的思想是:在陣列中選中乙個支點,以這個支點將陣列劃分成兩部分s1, s2,保證s1所有元素小於支點,s2不小於(用「不小於」好像嚴謹一些)支點。
現在,我們修改一下,讓s2中所有元素不小於支點,s2中所有元素小於支點。假設支點所在位置為i,那麼:
接下來給出**實現:
function swap(arr, i, j)
function partition(arr, low, high)
} swap(arr, low, m);
return m;
}function quick_sort(arr, low, high)
}function find_top_k(arr, low, high, k) else if (cnt < k)
}}
首先需要了解一下堆(二叉堆)的概念:
堆(英語:heap)是電腦科學中的一種特別的樹狀資料結構。若是滿足以下特性,即可稱為堆:「給定堆中任意節點p和c,若p是c的母節點,那麼p的值會小於等於(或大於等於)c的值」。若母節點的值恆小於等於子節點的值,此堆稱為最小堆(min heap);反之,若母節點的值恆大於等於子節點的值,此堆稱為最大堆(max heap)。在堆中最頂端的那乙個節點,稱作根節點(root node),根節點本身沒有母節點(parent node)。構建乙個最大堆:
function heapify(arr, start, end)
}for (let i = parseint(len / 2) - 1; i >= 0; i--)
堆排序:
function heap_sort(arr, len)
for (let i = len - 1; i > 0; i--)
}
如果理解了上面的**,那麼尋找最大k個數就很簡單了:
function heap_sort(arr, len)
for (let i = len - 1; i >= len - k; i--)
}
以上兩種方法都把時間複雜度從o(nlogn)優化了一些,變成了o(klogn)。 尋找最大的K個數 TOP K演算法
前言 本文是對程式設計之美第2.5節以及博文的一些總結和心得 問題描述 有很多個無序的數,怎麼從中選出其中最大的若干數呢?這個問題中的很多可以是幾個數也可以使成百上億的數,針對此問題我們有以下解法 解法一 咱們先簡單的理解,要求乙個序列中最小的k個數,按照慣有的思維方式,很簡單,先對這個序列從小到大...
尋找最大的K個數
方法一 改進的快速排序 分割槽時,根據數p將陣列分為兩部分,設大於p的數個數為a,小於p的數的個數為b。如果,a k,則從這a個數取最大的k個數,若a時間複雜度是o nlogk include includevoid swap float a,float b int fun float n,int ...
尋找陣列最大K個數
給定乙個無序陣列,找出最大的k個數。以下方法可以解決此類問題。快速排序中,其中最重要的一步是如何找到某個基準值的最終在陣列的存放位置index,找到這個位置index後,則index左邊的值全小於等於基準值,index右邊的值全大於基準值。在本題中要找top k大的數,那麼過程必須反著來,也即ind...