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

Ссылка на задачу — 2780. Minimum Index of a Valid Split.

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

💡 Идея

Для эффективного поиска доминирующего элемента хорошо подходит алгоритм большинства голосов Бойера — Мура.
Зная доминирующий элемент, можно пройти по массиву и в каждой возможной точке разделения отслеживать:

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

  1. Применяем алгоритм голосования большинства для нахождения доминанты.
  2. Подсчитываем точное количество его вхождений, чтобы использовать для отслеживания остатка справа.
  3. Идём по массиву от 1 до n - 1:
    • Обновляем количество слева и справа.
    • Проверяем условия доминирования в обеих частях:
      • 2 * left_count > left_size
      • 2 * remaining > right_size
  4. Возвращаем первый подходящий индекс, либо -1.

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

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

impl Solution {
    pub fn minimum_index(nums: Vec<i32>) -> i32 {
        let n = nums.len() as i32;
        // Find the dominant element and its total count in the array
        let (dominant, total_count) = Self::find_dominant(&nums);

        // Counters to track dominant element in the left & right subarrays
        let mut left_count = 0;
        let mut remaining = total_count;
        (1..n).find(|&left_size| {
                let right_size = n - left_size;
                if nums[left_size as usize - 1] == dominant {
                    left_count += 1;
                    remaining -= 1;
                }
                // Check if dominant element is dominant in both subarrays
                2 * left_count > left_size && 2 * remaining > right_size
            }).unwrap_or(0) - 1
    }

    /// Returns the dominant element and its total count.
    /// Assumes there is exactly one dominant element.
    fn find_dominant(nums: &[i32]) -> (i32, i32) {
        // Phase 1: Find candidate using Boyer-Moore algorithm
        let mut candidate = 0;
        let mut freq = 0;
        for &num in nums {
            if freq == 0 {
                candidate = num;
            }
            freq += if num == candidate { 1 } else { -1 };
        }

        // Phase 2: Count occurrences of the candidate
        let count = nums.iter().filter(|&&x| x == candidate).count() as _;
        (candidate, count)
    }
}

Tags: #rust #algorithms #dominant #counting