главная Π½ΠΎΠ²ΠΎΠ΅ Π»ΡƒΡ‡ΡˆΠ΅Π΅ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ

ΠžΡ‡Π΅Ρ€Π΅Π΄Π½Π°Ρ наша Π·Π°Π΄Π°Ρ‡Π° - 3381. Maximum Subarray Sum With Length Divisible by K

ОписаниС Π·Π°Π΄Π°Ρ‡ΠΈ

Π”Π°Π½ΠΎ Ρ†Π΅Π»ΠΎΠ΅ число k ΠΈ массив чисСл nums. НСобходимо Π½Π°ΠΉΡ‚ΠΈ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½ΡƒΡŽ сумму подмассива, Π΄Π»ΠΈΠ½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΊΡ€Π°Ρ‚Π½Π° k.

πŸš€ ИдСя

Данная Π·Π°Π΄Π°Ρ‡Π° Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅Ρ‚ классичСский Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ нахоТдСния максимальной суммы подмассива (Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ КаданС) для случаСв, ΠΊΠΎΠ³Π΄Π° Π΄Π»ΠΈΠ½Π° подмассива Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ ΠΊΡ€Π°Ρ‚Π½ΠΎΠΉ k. Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΡ‡Π΅ΡΡ‚ΡŒ это условиС, ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π±ΠΈΡ€Π°Π΅ΠΌ всС смСщСния Π² ΠΏΠΎΠ»ΡƒΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π»Π΅ [0,k) ΠΈ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ подмассивы с шагом k.

πŸ” ΠŸΠΎΠ΄Ρ…ΠΎΠ΄

  1. ΠŸΡ€Π΅Ρ„ΠΈΠΊΡΠ½Ρ‹Π΅ суммы:
    • ВычисляСм массив прСфиксных сумм, Ρ‡Ρ‚ΠΎΠ±Ρ‹ быстро Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ сумму любого подмассива.
  2. ΠŸΠ΅Ρ€Π΅Π±ΠΎΡ€ смСщСний:
    • Π˜Ρ‚Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌ ΠΏΠΎ всСм Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹ΠΌ Π½Π°Ρ‡Π°Π»ΡŒΠ½Ρ‹ΠΌ смСщСниям [0,k), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ подмассивы Π΄Π»ΠΈΠ½ΠΎΠΉ, ΠΊΡ€Π°Ρ‚Π½ΠΎΠΉ k.
  3. ΠœΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° КаданС:
    • Для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ смСщСния примСняСм Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ нахоТдСния максимальной суммы подмассива.
    • Если тСкущая сумма становится ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΉ, Π½Π°Ρ‡ΠΈΠ½Π°Π΅ΠΌ Π½ΠΎΠ²Ρ‹ΠΉ расчСт с Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ (сброс индСкса Π½Π°Ρ‡Π°Π»Π° подмассива).

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

Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ

impl Solution {
    pub fn max_subarray_sum(nums: Vec<i32>, k: i32) -> i64 {
        let n = nums.len();
        let k = k as usize;

        // Compute prefix sums
        let mut prefix_sums = vec![0i64; n + 1];
        for i in 0..n {
            prefix_sums[i + 1] = prefix_sums[i] + nums[i] as i64;
        }

        let mut best = i64::MIN;

        // Iterate over each offset
        for offset in 0..k {
            let mut start = offset;
            for end in (offset + k..=n).step_by(k) {
                // Calculate the subarray sum
                let subarray_sum = prefix_sums[end] - prefix_sums[start];
                // Update the best result
                best = best.max(subarray_sum);
                // Reset start if the current sum is negative
                if subarray_sum < 0 {
                    start = end;
                }
            }
        }

        best
    }
}