劍指offer 面試題30 最小的k個數

2021-07-26 07:30:54 字數 1557 閱讀 1587

題目描述:輸入n個整數,找出其中最小的k個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4.

題目分析:這道題最簡單的思路莫過於把n個整數排序,然後最前面的k個數就是最小的k個數,但是時間複雜度是o(nlogn)。我們應該想一想有沒有更快的方法。

解法一:o(n)的演算法,只有當可以修改輸入的陣列時可用。

基於快排裡的partition函式,基於陣列中的第k個數來調整,使得比第k個數小的都在左邊,比第k個數大的都在右邊。在隨機快速排序演算法中,我們先在陣列中隨機選擇乙個數字,然後調整陣列中數字的順序, 使得比選中的數字小的數字都排在它的左邊,比選中的數字大的數字都排在它的右邊。如果這個選中的數字的下標剛好是k,那麼這個數字之前的數字正好是最小的k個數。否則就遞迴尋找。

//最小的k個數

//快排partition函式

public

static

int partition(int numbers, int start, int end)

numbers[start] = numbers[end];

while (start < end && numbers[start] <= temp)

numbers[end] = numbers[start];

}numbers[start] = temp;

return start;

}//第一種方法

public

static

void getmink(int input, int output)

int start = 0;

int end = input.length - 1;

int k = output.length;

intindex = partition(input, start, end);

while (index != k) else

index = partition(input,start,end);

}system.arraycopy(input, 0, output, 0, output.length);

}

方法二:o(nlogk)的演算法,特別適合處理海量資料

我們可以先建立乙個大小為k的容器,然後依次讀入那n個數字,直到填滿容器,然後再讀入的數字就跟容器中的最大值做比較,如果大於最大值,則拋棄不用,繼續讀取下乙個數字,如果小於容器中最大值,就把它跟最大值替換。當n個數字讀完後,容器中就是最小的k個數。

容器填滿後,需要完成三個工作,乙個是從容器中找到最大值,二是有可能需要刪除最大值,三是有可能插入乙個新的數字。如果用二叉樹來實現這個容器,就能在o(logk)時間內完成。

//第二種方法

public

static treesetgetmink(int arr, int k)

treesettreeset = new treeset<>();

for (int i = 0; i < arr.length; i++) else}}

return treeset;

}

劍指offer 面試題30 最小的K個數

題目 輸入n個數,找出其中最小的k個數。例如輸入4 5 1 6 2 7 3 8這8個數字,則最小的4個數字是1,2,3,4。思路 這道題目是典型的top k問題。兩種方法 1 如果允許改變量列,半快速排序,是基準值正好為第k個數,那麼基準值左邊的都是小於它的,即可得到最小的k個數 求最大的過程類似 ...

劍指Offer 面試題30 最小的k個數

題目 輸入n個整數,找出其中最小的k個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,思路 1 首先,使用快排中的思路 每進行一次快排,會確定乙個位置上的數字,使得該位置前的數字都小於該數字,而該位置後的數字都大於該數字。2 所以,要找最小的k個數,即某一次快...

《劍指offer》面試題30 最小的k 個數

劍指offer 面試題30 最小的k 個數 1.題目描述 輸入n個整數,找出其中最小的k個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,2.解題思路 1。全排序。時間複雜度o nlogn 2。partiton思想 用快速排序,時間複雜度o n 3。最大堆 時...