leetcode_rust/
open_the_lock.rs1#![allow(dead_code)]
2
3pub fn open_lock(deadends: Vec<String>, target: String) -> i32 {
4 use std::collections::HashSet;
5 use std::collections::LinkedList;
6
7 let mut visited = HashSet::new();
8 let mut dead_ends = HashSet::new();
9 let target = target.into_bytes();
10 for s in deadends {
11 dead_ends.insert(s.into_bytes());
12 }
13 let mut q = LinkedList::new();
14 q.push_back((String::from("0000").into_bytes(), 0));
15
16 while !q.is_empty() {
17 let cur = q.pop_front().unwrap();
18 match dead_ends.get(&cur.0) {
19 Some(_) => {
20 continue;
21 }
22 None => {}
23 }
24
25 match visited.get(&cur.0) {
26 Some(_) => {
27 continue;
28 }
29 None => {
30 visited.insert(cur.0.clone());
31 }
32 }
33 if target == cur.0 {
34 return cur.1;
35 }
36 let neighbors = get_neighbors(cur.0);
37
38 for n in neighbors {
39 q.push_back((n, cur.1 + 1));
40 }
41 }
42
43 -1
44}
45
46fn get_neighbors(s: Vec<u8>) -> Vec<Vec<u8>> {
47 let mut neighbors = Vec::with_capacity(8);
48 let origin = s.clone();
49 for (i, &c) in s.iter().enumerate() {
50 let n;
51 if c == b'9' {
52 n = (b'8', b'0');
53 } else if c == b'0' {
54 n = (b'9', b'1');
55 } else {
56 n = (c + 1, c - 1);
57 }
58
59 let mut new = origin.clone();
60 new[i] = n.0;
61 neighbors.push(new);
62
63 let mut new = origin.clone();
64 new[i] = n.1;
65 neighbors.push(new);
66 }
67
68 neighbors
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn test1() {
77 let dead_ends = vec![
78 String::from("0201"),
79 String::from("0101"),
80 String::from("0102"),
81 String::from("1212"),
82 String::from("2002"),
83 ];
84
85 let res = open_lock(dead_ends, String::from("0202"));
86 assert_eq!(res, 6);
87
88 let dead_ends = vec![String::from("8888")];
89
90 let res = open_lock(dead_ends, String::from("0009"));
91 assert_eq!(res, 1);
92 }
93}