feat: add initial implementation of unique paths III solution

This commit is contained in:
SquidSpirit 2025-08-17 01:43:02 +08:00
parent 137adf2926
commit cd1b2b071d
3 changed files with 108 additions and 0 deletions

7
980_unique_path_3/Cargo.lock generated Normal file
View File

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "unique_path_3"
version = "0.1.0"

View File

@ -0,0 +1,6 @@
[package]
name = "unique_path_3"
version = "0.1.0"
edition = "2024"
[dependencies]

View File

@ -0,0 +1,95 @@
fn main() {
println!(
"{}",
Solution::unique_paths_iii(vec![vec![1, 0, 0, 0], vec![0, 0, 0, 0], vec![0, 0, 2, -1]])
);
}
struct Solution;
impl Solution {
pub fn unique_paths_iii(grid: Vec<Vec<i32>>) -> i32 {
let m = grid.len();
let n = grid.first().unwrap().len();
let mut initial_visited: Vec<Vec<bool>> =
vec![vec![false; grid.first().unwrap().len()]; grid.len()];
let mut start_point: (i32, i32) = (0, 0);
let mut end_point: (i32, i32) = (0, 0);
let mut left_blocks = (m * n) as i32;
for (i, inner_vec) in grid.iter().enumerate() {
for (j, &value) in inner_vec.iter().enumerate() {
match value {
1 => start_point = (i as i32, j as i32),
2 => end_point = (i as i32, j as i32),
-1 => {
initial_visited[i][j] = true;
left_blocks -= 1;
}
_ => {}
}
}
}
let mut dfs = DFS {
directions: vec![(1, 0), (0, 1), (-1, 0), (0, -1)],
end_point: end_point,
result: 0,
};
dfs.run(DFSParams {
point: start_point,
visited: initial_visited,
left_blocks: left_blocks - 1,
});
dfs.result
}
}
struct DFS {
directions: Vec<(i32, i32)>,
end_point: (i32, i32),
result: i32,
}
struct DFSParams {
point: (i32, i32),
visited: Vec<Vec<bool>>,
left_blocks: i32,
}
impl DFS {
fn run(&mut self, params: DFSParams) {
let mut stack: Vec<DFSParams> = vec![params];
while !stack.is_empty() {
let current = stack.pop().unwrap();
if current.point.0 < 0
|| current.point.1 < 0
|| current.point.0 >= current.visited.len() as i32
|| current.point.1 >= current.visited.first().unwrap().len() as i32
|| current.visited[current.point.0 as usize][current.point.1 as usize]
{
continue;
}
if current.point == self.end_point {
if current.left_blocks == 0 {
self.result += 1;
}
}
for &direction in &self.directions {
let mut new_visited = current.visited.clone();
new_visited[current.point.0 as usize][current.point.1 as usize] = true;
stack.push(DFSParams {
point: (current.point.0 + direction.0, current.point.1 + direction.1),
visited: new_visited,
left_blocks: current.left_blocks - 1,
});
}
}
}
}