-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathshortest_distance.rs
117 lines (94 loc) · 3.47 KB
/
shortest_distance.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use std::collections::HashMap;
use std::collections::VecDeque;
// 317. Shortest Distance from All Buildings, Hard
// https://leetcode.com/problems/shortest-distance-from-all-buildings/
impl Solution {
pub fn shortest_distance(grid: Vec<Vec<i32>>) -> i32 {
fn manhattan_distance(x0: i32, x1: i32, y0: i32, y1: i32) -> i32 {
i32::abs(x0 - x1) + i32::abs(y0 - y1)
}
fn dfs(grid: &Vec<Vec<i32>>, x: i32, y: i32) -> Vec<(i32, i32)> {
let mut dists: Vec<(i32, i32)> = vec![];
let directions: Vec<(i32, i32)> = vec![(1, 0), (-1, 0), (0, 1), (0, -1)];
let mut queue: VecDeque<(i32, i32)> = VecDeque::new();
let mut seen: Vec<(i32, i32)> = Vec::new();
queue.push_back((x, y));
while !queue.is_empty() {
let (x, y) = queue.pop_front().unwrap();
if x < 0 || x >= grid.len() as i32 || y < 0 || y >= grid[0].len() as i32 {
continue;
} else if seen.contains(&(x, y)) {
continue;
} else if grid[x as usize][y as usize] == 2 {
continue;
} else if grid[x as usize][y as usize] == 1 {
dists.push((x, y));
seen.push((x, y));
continue;
}
seen.push((x, y));
for (dx, dy) in directions.iter() {
let nx = x + dx;
let ny = y + dy;
queue.push_back((nx, ny));
}
}
dists
}
let rows = grid.len();
if rows == 0 {
return -1;
}
let cols = grid[0].len();
let mut dist_map: HashMap<i32, i32> = HashMap::new();
let mut friends = 0;
for r in 0..rows {
for c in 0..cols {
if grid[r][c] == 1 {
friends += 1;
}
if grid[r][c] == 0 {
let dists = dfs(&grid, r as i32, c as i32);
let mut curr_dist = 0;
for dist in dists.iter() {
curr_dist += manhattan_distance(r as i32, dist.0, c as i32, dist.1);
}
println!("{:?}", curr_dist);
dist_map.insert(dists.len() as i32, curr_dist.min(*dist_map.get(&(dists.len() as i32)).unwrap_or(&std::i32::MAX)));
}
}
}
println!("{:?}", dist_map);
*dist_map.get(&friends).unwrap_or(&-1)
}
}
struct Solution {}
#[cfg(test)]
mod tests {
use crate::vec_vec_i32;
use super::*;
#[test]
fn test_shortest_distance() {
assert_eq!(Solution::shortest_distance(vec_vec_i32![[1, 0, 2, 0, 1], [0, 0, 0, 0, 0], [0, 0, 1, 0, 0]]), 7);
}
#[test]
fn test_shortest_distance2() {
assert_eq!(Solution::shortest_distance(vec_vec_i32![[1, 0]]), 1);
}
#[test]
fn test_shortest_distance3() {
assert_eq!(Solution::shortest_distance(vec_vec_i32![[1]]), -1);
}
#[test]
fn test_shortest_distance4() {
assert_eq!(Solution::shortest_distance(vec_vec_i32![[1, 2, 0]]), -1);
}
#[test]
fn test_shortest_distance5() {
assert_eq!(Solution::shortest_distance(vec_vec_i32![[0, 2, 1], [1, 0, 2], [0, 1, 0]]), -1);
}
#[test]
fn test_shortest_distance6() {
assert_eq!(Solution::shortest_distance(vec_vec_i32![[1, 1], [0, 1]]), -1);
}
}