ΠΠ°Π΄Π°ΡΠ° Π½Π° ΡΠ΅Π³ΠΎΠ΄Π½Ρ 1368. Minimum Cost to Make at Least One Valid Path in a Grid - Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΡΡΠ°Π½Π΄Π°ΡΡΠ½Π°Ρ Π²Π°ΡΠΈΠ°ΡΠΈΡ Π»Π°Π±ΠΈΡΠΈΠ½ΡΠ° Ρ Π±Π΅ΡΠΏΠ»Π°ΡΠ½ΡΠΌΠΈ ΠΏΠ΅ΡΠ΅Ρ
ΠΎΠ΄Π°ΠΌΠΈ.
π ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ Π·Π°Π΄Π°ΡΠΈ
Π£ Π½Π°Ρ Π΅ΡΡΡ ΠΏΠΎΠ»Π΅ ΡΠ°Π·ΠΌΠ΅ΡΠΎΠΌ mΓn
, Π³Π΄Π΅ ΠΊΠ°ΠΆΠ΄Π°Ρ ΠΊΠ»Π΅ΡΠΊΠ° ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΡΠΊΠ°Π·Π°Π½ΠΈΠ΅ Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΡ. ΠΠ΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ Π½Π°ΠΉΡΠΈ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΡΡ ΡΡΠΎΠΈΠΌΠΎΡΡΡ ΠΏΠ΅ΡΠ΅Ρ
ΠΎΠ΄Π° ΠΈΠ· Π»Π΅Π²ΠΎΠ³ΠΎ Π²Π΅ΡΡ
Π½Π΅Π³ΠΎ ΡΠ³Π»Π° (0, 0)
Π² ΠΏΡΠ°Π²ΡΠΉ Π½ΠΈΠΆΠ½ΠΈΠΉ ΡΠ³ΠΎΠ» (mβ1,nβ1)
.
ΠΠ°ΠΆΠ΄Π°Ρ ΠΊΠ»Π΅ΡΠΊΠ° ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΡ:
1
β Π²ΠΏΡΠ°Π²ΠΎ,
2
β Π²Π»Π΅Π²ΠΎ,
3
β Π²Π½ΠΈΠ·,
4
β Π²Π²Π΅ΡΡ
.
ΠΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΏΠ΅ΡΠ΅Ρ
ΠΎΠ΄Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π½ΠΎ ΡΠΎ ΡΡΠΎΠΈΠΌΠΎΡΡΡΡ 1
, ΠΈ Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΡΠ°Π· Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΊΠ»Π΅ΡΠΊΠΈ.
π‘ ΠΠ΄Π΅Ρ
ΠΠΎΠ»Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ°ΡΡΠΌΠ°ΡΡΠΈΠ²Π°ΡΡ ΠΊΠ°ΠΊ ΠΎΡΠΈΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ Π³ΡΠ°Ρ, Π³Π΄Π΅ ΠΊΠ»Π΅ΡΠΊΠΈ ΡΠ²Π»ΡΡΡΡΡ Π²Π΅ΡΡΠΈΠ½Π°ΠΌΠΈ, Π° Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ Π·Π°Π΄Π°ΡΡ ΡΠ΅Π±ΡΠ°. ΠΠ°ΡΠ° ΡΠ΅Π»Ρ β Π½Π°ΠΉΡΠΈ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΡΡ ΡΡΠΎΠΈΠΌΠΎΡΡΡ ΠΏΡΡΠΈ ΠΈΠ· Π½Π°ΡΠ°Π»ΡΠ½ΠΎΠΉ ΠΊΠ»Π΅ΡΠΊΠΈ Π² ΠΊΠΎΠ½Π΅ΡΠ½ΡΡ. ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΌΠΎΠ΄ΠΈΡΠΈΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ BFS Ρ Π΄Π²ΡΠΌΡ ΠΎΡΠ΅ΡΠ΅Π΄ΡΠΌΠΈ, Π³Π΄Π΅ ΠΏΡΠΈΠΎΡΠΈΡΠ΅Ρ ΠΎΡΠ΄Π°Π΅ΡΡΡ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΡΠΌ Π±Π΅Π· ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ.
π οΈ ΠΠ΅ΡΠ°Π»ΠΈ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄Π°
- ΠΠ²Π΅ ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ:
current_queue
ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ ΠΊΠ»Π΅ΡΠΊΠΈ Ρ Π½ΡΠ»Π΅Π²ΠΎΠΉ ΡΡΠΎΠΈΠΌΠΎΡΡΡΡ ΠΏΠ΅ΡΠ΅Ρ
ΠΎΠ΄Π°.
next_queue
ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ ΠΊΠ»Π΅ΡΠΊΠΈ Ρ Π½Π΅Π½ΡΠ»Π΅Π²ΠΎΠΉ ΡΡΠΎΠΈΠΌΠΎΡΡΡΡ.
- ΠΡΠΎΡ
ΠΎΠ΄ BFS:
- ΠΠ»Π΅ΡΠΊΠΈ ΠΈΠ·
current_queue
ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡΡΡ Π² ΡΠ΅ΠΊΡΡΠ΅ΠΌ ΡΡΠΎΠ²Π½Π΅.
- ΠΡΠΈ ΠΏΠ΅ΡΠ΅Ρ
ΠΎΠ΄Π΅ Π½Π° ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΡΡΠΎΠ²Π΅Π½Ρ ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ ΠΌΠ΅Π½ΡΡΡΡΡ ΠΌΠ΅ΡΡΠ°ΠΌΠΈ, ΠΈ ΡΡΠΎΠΈΠΌΠΎΡΡΡ ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Π΅ΡΡΡ.
- ΠΠ°ΡΡΠΈΠ² ΡΠ°ΡΡΡΠΎΡΠ½ΠΈΠΉ:
- ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΌΠ°ΡΡΠΈΠ²
dist
, ΠΊΠΎΡΠΎΡΡΠΉ Ρ
ΡΠ°Π½ΠΈΡ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΡΡ ΡΡΠΎΠΈΠΌΠΎΡΡΡ ΠΏΠ΅ΡΠ΅Ρ
ΠΎΠ΄Π° ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΊΠ»Π΅ΡΠΊΠ΅ ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΎΡΡΠ΅ΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ ΠΊΠ»Π΅ΡΠΎΠΊ, ΡΠΆΠ΅ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°Π½Π½ΡΡ
Π½Π° ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅ΠΌ ΡΡΠΎΠ½ΡΠ΅.
- ΠΠ°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ:
- ΠΠ»Ρ ΠΏΠ΅ΡΠ΅Ρ
ΠΎΠ΄ΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΡΠΏΠΈΡΠΎΠΊ Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠΉ:
Π²ΠΏΡΠ°Π²ΠΎ
, Π²Π»Π΅Π²ΠΎ
, Π²Π½ΠΈΠ·
, Π²Π²Π΅ΡΡ
.
π ΠΡΠΈΠΌΠΏΡΠΎΡΠΈΠΊΠ°
- ΠΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ ΡΠ»ΠΎΠΆΠ½ΠΎΡΡΡ:
O(mΓn)
- ΠΠ°ΠΆΠ΄Π°Ρ ΠΊΠ»Π΅ΡΠΊΠ° ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΡΡΡ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ°Π·Π° Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΡΡΠΎΠ²Π½Π΅ BFS.
- ΠΠ»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΊΠ»Π΅ΡΠΊΠΈ ΠΏΡΠΎΠ²Π΅ΡΡΡΡΡΡ 4 Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ, ΡΡΠΎ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΊΠΎΠ½ΡΡΠ°Π½ΡΠ½ΡΠΌ ΡΠ°ΠΊΡΠΎΡΠΎΠΌ.
- ΠΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π΅Π½Π½Π°Ρ ΡΠ»ΠΎΠΆΠ½ΠΎΡΡΡ:
O(mΓn)
- ΠΠ°ΠΌΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ ΠΌΠ°ΡΡΠΈΠ²Π°
dist
, Π° ΡΠ°ΠΊΠΆΠ΅ Π΄Π»Ρ Π΄Π²ΡΡ
ΠΎΡΠ΅ΡΠ΅Π΄Π΅ΠΉ.
π₯οΈ ΠΡΡ
ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄
use std::collections::VecDeque;
impl Solution {
pub fn min_cost(grid: Vec<Vec<i32>>) -> i32 {
let m = grid.len();
let n = grid[0].len();
// Convert row and column to a single index
fn cell_index(r: usize, c: usize, n: usize) -> usize {
r * n + c
}
// Check if a cell is within bounds
fn is_valid_cell(r: i32, c: i32, m: usize, n: usize) -> bool {
r >= 0 && r < m as i32 && c >= 0 && c < n as i32
}
// Directions: right, left, down, up
let directions = vec![(0, 1), (0, -1), (1, 0), (-1, 0)];
// Distance array to track the minimum cost to reach each cell
let mut dist = vec![i32::MAX; m * n];
dist[cell_index(0, 0, n)] = 0;
// Two queues for BFS with prioritization
let mut current_queue: VecDeque<usize> = VecDeque::new();
let mut next_queue: VecDeque<usize> = VecDeque::new();
current_queue.push_back(cell_index(0, 0, n));
let mut current_cost = 0;
while !current_queue.is_empty() {
while let Some(cell) = current_queue.pop_front() {
// Early check: Skip if the cell has already been processed with a smaller cost
if dist[cell] > current_cost {
continue;
}
let r = cell / n;
let c = cell % n;
for (dir, (dx, dy)) in directions.iter().enumerate() {
let nr = r as i32 + dx;
let nc = c as i32 + dy;
if is_valid_cell(nr, nc, m, n) {
let next = cell_index(nr as usize, nc as usize, n);
let mut cost = 1;
// If the current cell's direction matches, no cost
if grid[r][c] == (dir as i32 + 1) {
cost = 0;
}
if dist[next] > current_cost + cost {
dist[next] = current_cost + cost;
if cost == 0 {
current_queue.push_back(next);
} else {
next_queue.push_back(next);
}
}
}
}
}
// Swap the queues and increment cost
std::mem::swap(&mut current_queue, &mut next_queue);
current_cost += 1;
}
// Return the minimum cost to reach the bottom-right corner
dist[cell_index(m - 1, n - 1, n)]
}
}