All original content is created in Ukrainian. Not all content has been translated yet. Some posts may only be available in Ukrainian.Learn more

Як знайти підмасив з максимальною сумою (Maximum Subarray Sum) в Ruby

Post cover: Як знайти підмасив з максимальною сумою (Maximum Subarray Sum) в Ruby
This content has not been translated yet.We're showing the original Ukrainian content below.
Розглянемо класичну задачу з алгоритмів: знайти підмасив з максимальною сумою.

Умова задачі

Ми маємо масив цілих чисел (позитивних, негативних або нулі). Потрібно знайти таку неперервну підпослідовність (subarray), сума якої — максимальна можлива.
max_sequence([-2, 1, -3, 4, -1, 2, 1, -5, 4])
# => 6, бо найбільша сума [4, -1, 2, 1]
Важливі моменти:
  • Якщо всі числа негативні — повертаємо 0.
  • Порожній масив також повертає 0.
  • Підмасив має бути неперервним (тобто всі елементи підряд).

Принцип розв’язання (Kadane’s Algorithm)

Ми будемо рухатися по масиву зліва направо, і на кожному кроці:
  1. Додаємо поточне число до проміжної суми current_sum.
  2. Якщо current_sum стала меншою за 0 — обнуляємо її.
  3. Запам’ятовуємо найбільше значення current_sum, яке зустрічалося — це і є наша відповідь.
Якщо сума стала менше 0, вона погіршує наступні значення, тому ми її скидаємо.
Реалізація в Ruby
(як і завжди, це один з можливих варіантів реалізації)
def max_sequence(arr)
  max_sum = 0
  current_sum = 0

  arr.each do |n|
    current_sum += n
    max_sum = [max_sum, current_sum].max
    current_sum = 0 if current_sum < 0
  end

  max_sum
end
Rspec для Ruby методу
RSpec.describe '#max_sequence' do
  it 'returns the maximum sum of a contiguous subsequence' do
    expect(max_sequence([])).to eq(0)
    expect(max_sequence([-1, -2, -3])).to eq(0)
    expect(max_sequence([1, 2, 3])).to eq(6)
    expect(max_sequence([-2, 1, -3, 4, -1, 2, 1, -5, 4])).to eq(6)
    expect(max_sequence([2, -1, 2, 3, 4, -5])).to eq(10)
    expect(max_sequence([-2, -3, 4, -1, -2, 1, 5, -3])).to eq(7)
  end
end

Просте пояснення

Уявімо, що ми йдемо по масиву і накопичуємо суму. Але якщо в якийсь момент ця сума стала негативною — все, далі вона тільки заважатиме. Ми її скидаємо і пробуємо знову.
Можна уявити, ніби ми шукаємо найвигіднішу ділянку дороги — де набрали найбільше "балів", не дозволяючи втратити все через одну погану яму.
Цей алгоритм підходить для задач типу "знайди найбільшу підпослідовність". Працює за O(n) — тобто дуже швидко. Простий для реалізації та тестування.

This post doesn't have any additions from the author yet.

24 Apr 20:17

Фіксимо minikube "You are trying to run the amd64 binary on an M1 system."

meme code
meme code@memecode
24 Apr 20:55

Фіксимо minikube на Mac з М1 (відмовляємось від qemu, запускаємо на docker)

meme code
meme code@memecode
Where can I find the older version of Google Chrome and download it? On the example of an old Mac
25 Apr 23:02

Where can I find the older version of Google Chrome and download it? On the example of an old Mac

meme code
meme code@memecode
09 May 19:27

[FIXED] cannot load such file -- html/pipeline (LoadError) виникає під час rails generate thredded:install

meme code
meme code@memecode
Задача: Перетворення римського числа на десяткове (Ruby)
20 May 12:05

Задача: Перетворення римського числа на десяткове (Ruby)

meme code
meme code@memecode
Задача на перевірку правильності розстановки дужок (Ruby)
21 May 10:27

Задача на перевірку правильності розстановки дужок (Ruby)

meme code
meme code@memecode
Google Ads for Dummies: A Step-by-Step Guide to a Successful Start
28 May 10:21

Google Ads for Dummies: A Step-by-Step Guide to a Successful Start

meme code
meme code@memecode
What jemalloc is and how it relates to Ruby /Ruby on Rails
30 May 11:53

What jemalloc is and how it relates to Ruby /Ruby on Rails

meme code
meme code@memecode
05 Jun 01:52

[Fixed] uninitialized constant ActiveSupport::LoggerThreadSafeLevel::Logger (NameError)

meme code
meme code@memecode
The preview in the network tab became very small after updating Chrome
05 Jun 18:23

The preview in the network tab became very small after updating Chrome

meme code
meme code@memecode
What is the HEIC format and why just rename it .jpg — is a bad idea
15 Jun 18:17

What is the HEIC format and why just rename it .jpg — is a bad idea

meme code
meme code@memecode
Чому вибір CMS важливий під час розробки сайту?
29 Jun 12:34

Чому вибір CMS важливий під час розробки сайту?

meme code
meme code@memecode