главная новое лучшее написать
3

Первая задача в этом году - 1422. Maximum Score After Splitting a String несложная, и интересно решить её за один проход по массиву.

📋 Описание задачи

Дана бинарная строка, состоящая из символов 0 и 1.
Требуется найти максимальный результат разбиения строки на две непустые подстроки.
Результат определяется как:

💡 Идея

Для эффективного решения задачи:

🔍 Подробности подхода

  1. Формула результата: Для разбиения в точке i:
    • Result = zero_count + (total_ones - ones_count)
      , где:
      • zero_count – число нулей слева
      • ones_count – число единиц слева (ones_count = i+1 - zero_count)
      • total_ones – число единиц во всей строке
  2. Упрощение формулы: Подставляем значение для ones_count
    • Result = 2 · zero_count - i - 1 + total_ones
    • Постоянную часть total_ones - 1 можно игнорировать и максимизировать:
    • balance = 2 · zero_count - i
  3. Итеративный процесс:
    • Увеличиваем zero_count, если встречаем 0.
    • Пропускаем последнюю итерацию, чтобы обе подстроки были непустыми.
    • Рассчитываем и обновляем max_balance.
  4. Финальная формула: После прохода по строке итоговый результат рассчитывается как:
    • Result = (str_length - zero_count) + max_balance-1

⏱️ Асимптотика

💻 Исходный код

impl Solution {
    pub fn max_score(s: String) -> i32 {
        let n = s.len();
        let mut zero_count = 0; // Number of zeros in the left part
        let mut max_balance = i32::MIN;

        // Iterate over the string
        for (i, c) in s.chars().enumerate() {
            if c == '0' {
                zero_count += 1; // Increase zeros number
            }

            // Pass the last iteration, because both substrings should be non empty
            if i + 1 < n {
                let balance = 2 * zero_count as i32 - i as i32;
                max_balance = max_balance.max(balance); // Update maximal balance
            }
        }

        // Final result calculations
        (n - 1) as i32 + max_balance - zero_count as i32
    }
}