مرحباً بالخوارزميات › الأكوام (Heaps) 10 / 19 السابق التالي

مسألة أعلى k

بمعطى مصفوفة غير مرتبة nums طولها nn، أعد أكبر kk عنصر في المصفوفة.

سنستعرض في هذه المسألة أولاً حلين مباشرين نسبياً، ثم حلاً أكثر كفاءة قائماً على الكومة.

الطريقة 1: الاختيار التكراري

يمكننا إجراء kk جولة من الاجتياز كما يوضح الشكل أدناه، فنستخرج في كل جولة العناصر 1st1^{st} و2nd2^{nd} و…\dots وkthk^{th} الأكبر، بتعقيد زمني O(nk)O(nk).

لا تناسب هذه الطريقة إلا الحالة k≪nk \ll n، لأنه عندما يقترب kk من nn يقترب التعقيد الزمني من O(n2)O(n^2)، وهو ما يجعل الكفاءة منخفضة جداً.

الاجتياز لإيجاد أكبر k عنصر

عندما k=nk = n يمكننا الحصول على متتالية مرتبة بالكامل، وهو ما يكافئ خوارزمية «ترتيب الاختيار».

الطريقة 2: الترتيب

كما يوضح الشكل أدناه، يمكننا أولاً ترتيب المصفوفة nums، ثم إعادة العناصر kk الواقعة في أقصى اليمين، بتعقيد زمني O(nlog⁡n)O(n \log n).

من الواضح أن هذه الطريقة تبذل جهداً أكبر من اللازم، لأننا نحتاج فقط إلى إيجاد أكبر kk عنصر بدلاً من ترتيب العناصر الأخرى.

الترتيب لإيجاد أكبر k عنصر

الطريقة 3: الكومة

يمكننا حل مسألة أعلى k بكفاءة أكبر باستخدام كومة، كما يوضح الشكل أدناه.

  1. نهيّئ كومة صغرى، حيث يكون العنصر الأعلى في الكومة هو الأصغر.
  2. ندرج أولاً العناصر kk الأولى من المصفوفة في الكومة بالتتابع.
  3. بدءاً من العنصر (k+1)th(k + 1)^{th}، إذا كان العنصر الحالي أكبر من العنصر الأعلى في الكومة، نحذف العنصر الأعلى من الكومة وندرج العنصر الحالي فيها.
  4. بعد اكتمال الاجتياز، تحتوي الكومة على أكبر kk عنصر.

وتكون شيفرة المثال كما يلي:

يُجري ما مجموعه nn جولة من الإدراج والحذف في الكومة، ويكون الحد الأقصى لطول الكومة kk، لذا يكون التعقيد الزمني O(nlog⁡k)O(n \log k). وهذه الطريقة عالية الكفاءة؛ فعندما يكون kk صغيراً يقترب التعقيد الزمني من O(n)O(n)، وعندما يكون kk كبيراً لا يتجاوز التعقيد الزمني O(nlog⁡n)O(n \log n).

وإضافة إلى ذلك، تلائم هذه الطريقة تدفّقات البيانات الديناميكية. فمع وصول بيانات جديدة، يمكننا مواصلة صيانة العناصر في الكومة، بما يتيح التحديث الديناميكي لأكبر kk عنصر.