89 lines
2.6 KiB
Rust
89 lines
2.6 KiB
Rust
pub 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,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|