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

ΠžΡ‡Π΅Ρ€Π΅Π΄Π½Π°Ρ Π·Π°Π΄Π°Ρ‡Π°: 2290. Minimum Obstacle Removal to Reach Corner.

πŸ“„ ОписаниС Π·Π°Π΄Π°Ρ‡ΠΈ

Π”Π°Π½Π° двумСрная ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π° grid Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠΌ m x n, Π³Π΄Π΅ каТдая ΠΊΠ»Π΅Ρ‚ΠΊΠ° ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π»ΠΈΠ±ΠΎ пустой (0), Π»ΠΈΠ±ΠΎ прСпятствиСм (1), ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ. Π—Π°Π΄Π°Ρ‡Π° Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π°ΠΉΡ‚ΠΈ минимальноС количСство прСпятствий, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½ΡƒΠΆΠ½ΠΎ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠΉΡ‚ΠΈ ΠΈΠ· Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ Π»Π΅Π²ΠΎΠ³ΠΎ ΡƒΠ³Π»Π° (0, 0) Π² Π½ΠΈΠΆΠ½ΠΈΠΉ ΠΏΡ€Π°Π²Ρ‹ΠΉ ΡƒΠ³ΠΎΠ» (m-1, n-1), ΠΏΠ΅Ρ€Π΅Π΄Π²ΠΈΠ³Π°ΡΡΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎ пустым ΠΊΠ»Π΅Ρ‚ΠΊΠ°ΠΌ ΠΈΠ»ΠΈ удаляя прСпятствия.

πŸ”‘ ИдСя

Для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π·Π°Π΄Π°Ρ‡ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° поиска Π² ΡˆΠΈΡ€ΠΈΠ½Ρƒ (BFS), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ эффСктивно ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ прСпятствия. ВмСсто ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΠ»Π΅Ρ‚ΠΎΠΊ ΠΏΠΎ Ρ€Π°ΡΡΡ‚ΠΎΡΠ½ΠΈΡŽ, ΠΊΠ°ΠΊ Π² стандартном Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ΅ ДСйкстры, Π² 0-1 BFS (ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‚Π°ΠΊ эту ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ принято Π½Π°Π·Ρ‹Π²Π°Ρ‚ΡŒ) ΠΌΡ‹ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ сначала пустыС ΠΊΠ»Π΅Ρ‚ΠΊΠΈ, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΊΠ»Π΅Ρ‚ΠΊΠΈ с прСпятствиями, Ρ‡Ρ‚ΠΎ позволяСт Π½Π°ΠΌ ΠΌΠΈΠ½ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ количСство удаляСмых прСпятствий.

πŸ“‹ ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠ΅ описаниС ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π°

  1. Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ: ΠœΡ‹ создаСм Π΄Π²Π΅ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ: front ΠΈ back. Π’ΠΎ front ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅ΠΌ ΠΊΠ»Π΅Ρ‚ΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠΉΡ‚ΠΈ Π±Π΅Π· удалСния прСпятствий, Π° Π² back β€” ΠΊΠ»Π΅Ρ‚ΠΊΠΈ, для ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… потрСбуСтся ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ прСпятствиС.
  2. Поиск Π² ΡˆΠΈΡ€ΠΈΠ½Ρƒ (BFS):
    • НачинаСм с Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ Π»Π΅Π²ΠΎΠ³ΠΎ ΡƒΠ³Π»Π° ΠΈ устанавливаСм расстояниС для этой ΠΊΠ»Π΅Ρ‚ΠΊΠΈ Π² 0 (Ρ‚.Π΅. прСпятствий Π΅Ρ‰Π΅ Π½Π΅ ΡƒΠ΄Π°Π»Π΅Π½ΠΎ).
    • Если ΠΊΠ»Π΅Ρ‚ΠΊΠ° пустая (Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 0), ΠΌΡ‹ добавляСм Π΅Ρ‘ Π² front. Если ΠΊΠ»Π΅Ρ‚ΠΊΠ° β€” прСпятствиС (Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 1), Ρ‚ΠΎ Π² back.
    • Π’ процСссС BFS ΠΌΡ‹ сначала ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ ΠΊΠ»Π΅Ρ‚ΠΊΠΈ ΠΈΠ· front (Π³Π΄Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠΉΡ‚ΠΈ Π±Π΅Π· удалСния прСпятствий), Π° Ссли front пуст, мСняСм мСстами front ΠΈ back, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ ΠΊΠ»Π΅Ρ‚ΠΎΠΊ с прСпятствиями.
  3. НаправлСния двиТСния: Для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΊΠ»Π΅Ρ‚ΠΊΠΈ ΠΌΡ‹ провСряСм всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ направлСния (Π²Π²Π΅Ρ€Ρ…, Π²Π½ΠΈΠ·, Π²Π»Π΅Π²ΠΎ, Π²ΠΏΡ€Π°Π²ΠΎ) ΠΈ, Ссли ΠΊΠ»Π΅Ρ‚ΠΊΠ° Π² ΠΏΡ€Π΅Π΄Π΅Π»Π°Ρ… Π³Ρ€Π°Π½ΠΈΡ† ΠΈ ΠΏΡƒΡ‚ΡŒ ΠΊ Π½Π΅ΠΉ Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΈΠΉ, обновляСм Π΅Ρ‘ расстояниС.
  4. Π—Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅: Алгоритм Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡΡ, ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ достигнСм ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ Π½ΠΈΠΆΠ½Π΅Π³ΠΎ ΡƒΠ³Π»Π°. Π’Π΅Π»ΠΈΡ‡ΠΈΠ½Π° Π² массивС расстояний для этой ΠΊΠ»Π΅Ρ‚ΠΊΠΈ ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌ количСством ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹Ρ… прСпятствий.

Π‘Π»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ

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

impl Solution {
    pub fn minimum_obstacles(grid: Vec<Vec<i32>>) -> i32 {
        let rows = grid.len();
        let cols = grid[0].len();

        // Directions for moving up, down, left, and right
        let directions = vec![
            (-1, 0), (1, 0), (0, -1), (0, 1),
        ];

        // Distance array initialized to a large value
        let mut dist = vec![vec![i32::MAX; cols]; rows];

        // Two deques: front and back (we'll use Vec as Queue backbone for efficient push and pop)
        let mut front = Vec::new();
        let mut back = Vec::new();
        let mut front_idx = 0;

        // Start from the top-left corner (cellId = (0, 0))
        dist[0][0] = 0;
        front.push((0, 0)); // Add the (row, col) tuple for the starting point

        // Perform BFS
        while !front.is_empty() {
            while front_idx < front.len() {
                // Pop from the front slice (get the (row, col) tuple)
                let (row, col) = front.pop().unwrap();

                for (dr, dc) in &directions {
                    let new_row = row + dr;
                    let new_col = col + dc;

                    // Check if the new position is within bounds
                    if new_row >= 0 && new_row < rows as i32 && new_col >= 0 && new_col < cols as i32 {
                        let new_row = new_row as usize;
                        let new_col = new_col as usize;
                        let new_dist = dist[row as usize][col as usize] + grid[new_row][new_col];

                        // Update distance if a better path is found
                        if new_dist < dist[new_row][new_col] {
                            dist[new_row][new_col] = new_dist;
                            if grid[new_row][new_col] == 0 {
                                // Empty cell: push to the front slice
                                front.push((new_row as i32, new_col as i32));
                            } else {
                                // Obstacle cell: push to the back slice
                                back.push((new_row as i32, new_col as i32));
                            }
                        }
                    }
                }
            }
            // swap front and back
            std::mem::swap(&mut front, &mut back);
        }

        // Return the distance to the bottom-right cell
        dist[rows - 1][cols - 1]
    }
}

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅

Π›Π΅Π³ΠΊΠΎ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π² Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ΅ вмСсто 2 ΠΎΡ‡Π΅Ρ€Π΅Π΄Π΅ΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ 1 Π΄Π΅ΠΊ, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½Ρ‹Π΅ Π²Π΅Ρ€ΡˆΠΈΠ½Ρ‹ ΠΏΡƒΡˆΠΈΡ‚ΡŒ Π»ΠΈΠ±ΠΎ Π² Π½Π°Ρ‡Π°Π»ΠΎ (0), Π»ΠΈΠ±ΠΎ Π² ΠΊΠΎΠ½Π΅Ρ† (1).