مجموعة فرعية قصوى
الإدخال هو مصفوفة من الأرقام ، على سبيل المثال arr = [1, -2, 3, 4, -9, 6].
المهمة هي: العثور على مصفوفة متجاورة من arr مع العدد الأقصى للعناصر.
اكتب الداله getMaxSubSum(arr) التي سوف تعيد الجمع.
علي سبيل المثال:
getMaxSubSum([-1, 2, 3, -9]) == 5 (مجموع العناصر المميزة) getMaxSubSum([2, -1, 2, 3, -9]) == 6 getMaxSubSum([-1, 2, 3, -9, 11]) == 11 getMaxSubSum([-2, -1, 1, 2]) == 3 getMaxSubSum([100, -9, 2, -3, 5]) == 100 getMaxSubSum([1, 2, 3]) == 6 (خذها كلها) إذا كانت جميع العناصر سالبة ، فهذا يعني أننا لا نأخذ أي منها (المصفوفة فارغة) ، لذا يكون المجموع صفرًا:
getMaxSubSum([-1, -2, -3]) = 0 من فضلك فكر في أسرع حل: O(n2) أو حتى O (n) إذا استطعت.
الحل الأبطئ
يمكننا حساب جميع الفئات الفرعية الممكنة.
إن أبسط طريقة هي أخذ كل عنصر وحساب جميع المصفوفات الفرعية بدءًا منها.
علي سبيل المثال, for [-1, 2, 3, -9, 11]:
// البدء من -1: -1 - 1 + 2 - 1 + 2 + 3 - 1 + 2 + 3 + -9 - 1 + 2 + 3 + -9 + 11; // البدء من 2: 2; 2 + 3; 2 + 3 + -9; 2 + 3 + -9 + 11; // البدء من 3: 3; 3 + -9; 3 + -9 + 11 - // البدء من -9 9 - 9 + 11; // البدء من 11 11; الكود هو في الواقع حلقة متداخلة: الحلقة الخارجية فوق عناصر المصفوفه ، والعد الداخلي يحسب الفئات الفرعية التي تبدأ بالعنصر الحالي.
function getMaxSubSum(arr) { let maxSum = 0; // إذا لم نأخذ أي عناصر ، فسيتم إرجاع الصفر for (let i = 0; i < arr.length; i++) { let sumFixedStart = 0; for (let j = i; j < arr.length; j++) { sumFixedStart += arr[j]; maxSum = Math.max(maxSum, sumFixedStart); } } return maxSum; } alert(getMaxSubSum([-1, 2, 3, -9])); // 5 alert(getMaxSubSum([-1, 2, 3, -9, 11])); // 11 alert(getMaxSubSum([-2, -1, 1, 2])); // 3 alert(getMaxSubSum([1, 2, 3])); // 6 alert(getMaxSubSum([100, -9, 2, -3, 5])); // 100 The solution has a time complexity of O(n2). In other words, if we increase the array size 2 times, the algorithm will work 4 times longer.
الحل الأسرع
دعنا نسير في المصفوفة ونحتفظ بالمجموع الجزئي الحالي للعناصر في المتغير s. إذا أصبحت s سالبة في وقت ما ، قم بتعيينs = 0. سيكون الحد الأقصى لكل هذه الإجابات هو الإجابة.
إذا كان الوصف غامضًا جدًا ، فيرجى الاطلاع على الكود ، فهو قصير بما يكفي:
function getMaxSubSum(arr) { let maxSum = 0; let partialSum = 0; for (let item of arr) { // لكل عنصر في المصفوفه partialSum += item; // أضفه إلى مجموع الجزئي maxSum = Math.max(maxSum, partialSum); // تذكر الحد الأقصى if (partialSum < 0) partialSum = 0; // صفر إذا كانت سلبية } return maxSum; } alert(getMaxSubSum([-1, 2, 3, -9])); // 5 alert(getMaxSubSum([-1, 2, 3, -9, 11])); // 11 alert(getMaxSubSum([-2, -1, 1, 2])); // 3 alert(getMaxSubSum([100, -9, 2, -3, 5])); // 100 alert(getMaxSubSum([1, 2, 3])); // 6 alert(getMaxSubSum([-1, -2, -3])); // 0 تتطلب الخوارزمية تمريراً مصفوفه واحده ، لذا فإن تعقيد الوقت هو O (n).
يمكنك العثور على مزيد من المعلومات التفصيلية حول الخوارزمية هنا: Maximum subarray problem. إذا كان لا يزال من غير الواضح سبب نجاح ذلك ، فالرجاء تتبع الخوارزمية في الأمثلة أعلاه ، ومعرفة كيفية عملها ، وهذا أفضل من أي كلمات.