上位Kの質問は面接でよく試される質問で、ソート(並べ替え)やヒープ(大小のルートヒープ)で解けることが多いです。もちろん、すぐに列に並ぶことができるだけであれば、面接を早く終えて夕食のために家に帰ることもできます。
結論は:
上位 K 問題はヒープで解決されることがよくあります
1. 配列内の最小の k 数値を見つけます。
トピック:
配列内の最小の k 数値を見つけるアルゴリズムを設計します。k 数値は任意の順序で返すことができます。
例:
输入: arr = [1,3,5,7,2,4,6,8], k = 4
输出: [1,2,3,4]
1.1 クイックソート、O(nlogn)、O(logn)
最も簡単に考えられる方法は、時間計算量が O(nlogn) で空間計算量が O(logn) のクイック ソートです。
コード:
class Solution:
def smallestK(self, arr: List[int], k: int) -> List[int]:
arr.sort()
return arr[:k]
1.2 ビッグルートヒープ、O(nlogk)、O(k)
配列の上位 k 個の小さな値をリアルタイムで維持するために、大きなルート ヒープを使用します。最初に最初の k 個の数値をビッグ ルート ヒープに挿入し、次に k+1 番目の数値からトラバースを開始します。現在トラバースされている数値がビッグ ルート ヒープの先頭にある数値より小さい場合は、ヒープの先頭にある数値をポップしてから、現在トラバースされている数値を挿入します。最後に、ビッグ ルート ヒープの数値を配列に格納して返します。
Python の heapq ライブラリによって作成されるヒープは小さなルート ヒープであるため、大きなルート ヒープにするには、配列内のすべての数値の逆を取る必要があります。
コード:
class Solution:
def smallestK(self, arr: List[int], k: int) -> List[int]:
if not arr or k==0:
return []
heap=[-x for x in arr[:k]]
heapq.heapify(heap)
for x in arr[k:]:
if -heap[0]>x:
heapq.heappop(heap)
heapq.heappush(heap,-x)
return [-x for x in heap]
複雑さの分析:
- 時間計算量: O(nlogk)、n は配列 arr の長さです。大きなルート ヒープは最初の k 個の小さな値をリアルタイムで維持するため、挿入と削除の時間計算量は O(logk) ですが、最悪の場合、配列内の n 個の数値が挿入されるため、合計の時間計算量は O(nlogk) が必要です。
- 空間計算量: O(k)、大きなルート ヒープには最大でも k 個の数値が存在するため
関連トピックは継続的に更新されています...