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

Ссылка на задачу – 3105. Longest Strictly Increasing or Strictly Decreasing Subarray.

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

Дан массив целых чисел nums. Необходимо найти длину самой длинной последовательности, которая является либо строго возрастающей, либо строго убывающей.

🤔 Идея

Разбить массив на группы (чанки) по непрерывной монотонности (либо возрастающей, либо убывающей).
Для каждой группы вычислить её длину, а затем выбрать максимальное значение среди всех групп.

🚀 Детали подхода

  1. Разбиение на чанки:
    Используем метод chunk_by для разбиения массива:
    • Для строго возрастающей последовательности используем сравнение a < b.
    • Для строго убывающей последовательности используем сравнение a > b.
  2. Вычисление максимальной длины:
    • Для каждого набора чанков вычисляем длину каждой группы, выбираем максимальную длину для возрастающих и убывающих групп.
  3. Результат:
    • Возвращаем максимум между максимальной длиной возрастающей и максимальной длиной убывающей последовательности.

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

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

impl Solution {
    pub fn longest_monotonic_subarray(nums: Vec<i32>) -> i32 {
        // Group strictly increasing segments using chunk_by
        let max_increasing_len = nums.chunk_by(|a, b| a < b)
            .map(|c| c.len()).max().unwrap_or(0);

        // Group strictly decreasing segments using chunk_by
        let max_decreasing_len = nums.chunk_by(|a, b| a > b)
            .map(|c| c.len()).max().unwrap_or(0);

        max_increasing_len.max(max_decreasing_len) as i32
    }
}

Tags: #rust #algorithms #iterators

2 leetcoder 03-02-2025

Можно предоставить также и решение за один проход.
Мне кажется, что оно менее изящно. Но всё-равно имеет право быть упомянутым:

use std::cmp::Ordering;

impl Solution {
    pub fn longest_monotonic_subarray(nums: Vec<i32>) -> i32 {
        nums.windows(2).fold((1, 1, 1), |(max_chain, inc_chain, dec_chain), w| {
            match w[1].cmp(&w[0]) {
                // extend decreasing chain; reset increasing chain; update max_chain
                Ordering::Less => (max_chain.max(dec_chain + 1), 1, dec_chain + 1),
                // reset both chains on equal elements
                Ordering::Equal => (max_chain, 1, 1), 
                // extend increasing chain; reset decreasing chain; update max_chain
                Ordering::Greater => (max_chain.max(inc_chain + 1), inc_chain + 1, 1),
            }
        }).0
    }
}
ответить