Skip to content

Commit 29fac55

Browse files
authored
feat: add rust solution to lc problem: No.1197 (#1169)
1 parent 05880c3 commit 29fac55

File tree

3 files changed

+324
-0
lines changed

3 files changed

+324
-0
lines changed

solution/1100-1199/1197.Minimum Knight Moves/README.md

+135
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,141 @@ public:
293293
};
294294
```
295295

296+
### **Rust**
297+
298+
```rust
299+
use std::collections::VecDeque;
300+
301+
const DIR: [(i32, i32); 8] = [(-2, 1), (2, 1), (-1, 2), (1, 2), (2, -1), (-2, -1), (1, -2), (-1, -2)];
302+
303+
impl Solution {
304+
#[allow(dead_code)]
305+
pub fn min_knight_moves(x: i32, y: i32) -> i32 {
306+
// The original x, y are from [-300, 300]
307+
// Let's shift them to [0, 600]
308+
let x: i32 = x + 300;
309+
let y: i32 = y + 300;
310+
let mut ret = -1;
311+
let mut vis: Vec<Vec<bool>> = vec![vec![false; 618]; 618];
312+
// <X, Y, Current Steps>
313+
let mut q: VecDeque<(i32, i32, i32)> = VecDeque::new();
314+
315+
q.push_back((300, 300, 0));
316+
317+
while !q.is_empty() {
318+
let (i, j, s) = q.front().unwrap().clone();
319+
q.pop_front();
320+
if i == x && j == y {
321+
ret = s;
322+
break;
323+
}
324+
Self::enqueue(&mut vis, &mut q, i, j, s);
325+
}
326+
327+
ret
328+
}
329+
330+
#[allow(dead_code)]
331+
fn enqueue(vis: &mut Vec<Vec<bool>>, q: &mut VecDeque<(i32, i32, i32)>, i: i32, j: i32, cur_step: i32) {
332+
let next_step = cur_step + 1;
333+
for (dx, dy) in DIR {
334+
let x = i + dx;
335+
let y = j + dy;
336+
if Self::check_bounds(x, y) || vis[x as usize][y as usize] {
337+
// This <X, Y> pair is either out of bound, or has been visited before
338+
// Just ignore this pair
339+
continue;
340+
}
341+
// Otherwise, add the pair to the queue
342+
// Also remember to update the vis vector
343+
vis[x as usize][y as usize] = true;
344+
q.push_back((x, y, next_step));
345+
}
346+
}
347+
348+
#[allow(dead_code)]
349+
fn check_bounds(i: i32, j: i32) -> bool {
350+
i < 0 || i > 600 || j < 0 || j > 600
351+
}
352+
}
353+
```
354+
355+
双向 BFS:
356+
357+
```rust
358+
use std::collections::VecDeque;
359+
use std::collections::HashMap;
360+
361+
const DIR: [(i32, i32); 8] = [(-2, 1), (2, 1), (-1, 2), (1, 2), (2, -1), (-2, -1), (1, -2), (-1, -2)];
362+
363+
impl Solution {
364+
#[allow(dead_code)]
365+
pub fn min_knight_moves(x: i32, y: i32) -> i32 {
366+
if x == 0 && y == 0 {
367+
return 0;
368+
}
369+
// Otherwise, let's shift <X, Y> from [-300, 300] -> [0, 600]
370+
let x = x + 300;
371+
let y = y + 300;
372+
let mut ret = -1;
373+
// Initialize the two hash map, used to track if a node has been visited
374+
let mut map_to: HashMap<i32, i32> = HashMap::new();
375+
let mut map_from: HashMap<i32, i32> = HashMap::new();
376+
// Input the original status
377+
map_to.insert(601 * 300 + 300, 0);
378+
map_from.insert(601 * x + y, 0);
379+
let mut q_to: VecDeque<(i32, i32)> = VecDeque::new();
380+
let mut q_from: VecDeque<(i32, i32)> = VecDeque::new();
381+
// Initialize the two queue
382+
q_to.push_back((300, 300));
383+
q_from.push_back((x, y));
384+
385+
while !q_to.is_empty() && !q_from.is_empty() {
386+
let step = if q_to.len() < q_from.len() {
387+
Self::extend(&mut map_to, &mut map_from, &mut q_to)
388+
} else {
389+
Self::extend(&mut map_from, &mut map_to, &mut q_from)
390+
};
391+
if step != -1 {
392+
ret = step;
393+
break;
394+
}
395+
}
396+
397+
ret
398+
}
399+
400+
#[allow(dead_code)]
401+
fn extend(map_to: &mut HashMap<i32, i32>, map_from: &mut HashMap<i32, i32>, cur_q: &mut VecDeque<(i32, i32)>) -> i32 {
402+
let n = cur_q.len();
403+
for _ in 0..n {
404+
let (i, j) = cur_q.front().unwrap().clone();
405+
cur_q.pop_front();
406+
// The cur_step here must exist
407+
let cur_step = map_to.get(&(601 * i + j)).unwrap().clone();
408+
for (dx, dy) in DIR {
409+
let x = i + dx;
410+
let y = j + dy;
411+
// Check if this node has been visited
412+
if map_to.contains_key(&(601 * x + y)) {
413+
// Just ignore this node
414+
continue;
415+
}
416+
// Check if this node has been visited by the other side
417+
if map_from.contains_key(&(601 * x + y)) {
418+
// We found the node
419+
return cur_step + 1 + map_from.get(&(601 * x + y)).unwrap().clone();
420+
}
421+
// Otherwise, update map_to and push the new node to queue
422+
map_to.insert(601 * x + y, cur_step + 1);
423+
cur_q.push_back((x, y));
424+
}
425+
}
426+
-1
427+
}
428+
}
429+
```
430+
296431
### **Go**
297432

298433
```go

solution/1100-1199/1197.Minimum Knight Moves/README_EN.md

+135
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,141 @@ public:
272272
};
273273
```
274274

275+
### **Rust**
276+
277+
```rust
278+
use std::collections::VecDeque;
279+
280+
const DIR: [(i32, i32); 8] = [(-2, 1), (2, 1), (-1, 2), (1, 2), (2, -1), (-2, -1), (1, -2), (-1, -2)];
281+
282+
impl Solution {
283+
#[allow(dead_code)]
284+
pub fn min_knight_moves(x: i32, y: i32) -> i32 {
285+
// The original x, y are from [-300, 300]
286+
// Let's shift them to [0, 600]
287+
let x: i32 = x + 300;
288+
let y: i32 = y + 300;
289+
let mut ret = -1;
290+
let mut vis: Vec<Vec<bool>> = vec![vec![false; 618]; 618];
291+
// <X, Y, Current Steps>
292+
let mut q: VecDeque<(i32, i32, i32)> = VecDeque::new();
293+
294+
q.push_back((300, 300, 0));
295+
296+
while !q.is_empty() {
297+
let (i, j, s) = q.front().unwrap().clone();
298+
q.pop_front();
299+
if i == x && j == y {
300+
ret = s;
301+
break;
302+
}
303+
Self::enqueue(&mut vis, &mut q, i, j, s);
304+
}
305+
306+
ret
307+
}
308+
309+
#[allow(dead_code)]
310+
fn enqueue(vis: &mut Vec<Vec<bool>>, q: &mut VecDeque<(i32, i32, i32)>, i: i32, j: i32, cur_step: i32) {
311+
let next_step = cur_step + 1;
312+
for (dx, dy) in DIR {
313+
let x = i + dx;
314+
let y = j + dy;
315+
if Self::check_bounds(x, y) || vis[x as usize][y as usize] {
316+
// This <X, Y> pair is either out of bound, or has been visited before
317+
// Just ignore this pair
318+
continue;
319+
}
320+
// Otherwise, add the pair to the queue
321+
// Also remember to update the vis vector
322+
vis[x as usize][y as usize] = true;
323+
q.push_back((x, y, next_step));
324+
}
325+
}
326+
327+
#[allow(dead_code)]
328+
fn check_bounds(i: i32, j: i32) -> bool {
329+
i < 0 || i > 600 || j < 0 || j > 600
330+
}
331+
}
332+
```
333+
334+
Two-end BFS:
335+
336+
```rust
337+
use std::collections::VecDeque;
338+
use std::collections::HashMap;
339+
340+
const DIR: [(i32, i32); 8] = [(-2, 1), (2, 1), (-1, 2), (1, 2), (2, -1), (-2, -1), (1, -2), (-1, -2)];
341+
342+
impl Solution {
343+
#[allow(dead_code)]
344+
pub fn min_knight_moves(x: i32, y: i32) -> i32 {
345+
if x == 0 && y == 0 {
346+
return 0;
347+
}
348+
// Otherwise, let's shift <X, Y> from [-300, 300] -> [0, 600]
349+
let x = x + 300;
350+
let y = y + 300;
351+
let mut ret = -1;
352+
// Initialize the two hash map, used to track if a node has been visited
353+
let mut map_to: HashMap<i32, i32> = HashMap::new();
354+
let mut map_from: HashMap<i32, i32> = HashMap::new();
355+
// Input the original status
356+
map_to.insert(601 * 300 + 300, 0);
357+
map_from.insert(601 * x + y, 0);
358+
let mut q_to: VecDeque<(i32, i32)> = VecDeque::new();
359+
let mut q_from: VecDeque<(i32, i32)> = VecDeque::new();
360+
// Initialize the two queue
361+
q_to.push_back((300, 300));
362+
q_from.push_back((x, y));
363+
364+
while !q_to.is_empty() && !q_from.is_empty() {
365+
let step = if q_to.len() < q_from.len() {
366+
Self::extend(&mut map_to, &mut map_from, &mut q_to)
367+
} else {
368+
Self::extend(&mut map_from, &mut map_to, &mut q_from)
369+
};
370+
if step != -1 {
371+
ret = step;
372+
break;
373+
}
374+
}
375+
376+
ret
377+
}
378+
379+
#[allow(dead_code)]
380+
fn extend(map_to: &mut HashMap<i32, i32>, map_from: &mut HashMap<i32, i32>, cur_q: &mut VecDeque<(i32, i32)>) -> i32 {
381+
let n = cur_q.len();
382+
for _ in 0..n {
383+
let (i, j) = cur_q.front().unwrap().clone();
384+
cur_q.pop_front();
385+
// The cur_step here must exist
386+
let cur_step = map_to.get(&(601 * i + j)).unwrap().clone();
387+
for (dx, dy) in DIR {
388+
let x = i + dx;
389+
let y = j + dy;
390+
// Check if this node has been visited
391+
if map_to.contains_key(&(601 * x + y)) {
392+
// Just ignore this node
393+
continue;
394+
}
395+
// Check if this node has been visited by the other side
396+
if map_from.contains_key(&(601 * x + y)) {
397+
// We found the node
398+
return cur_step + 1 + map_from.get(&(601 * x + y)).unwrap().clone();
399+
}
400+
// Otherwise, update map_to and push the new node to queue
401+
map_to.insert(601 * x + y, cur_step + 1);
402+
cur_q.push_back((x, y));
403+
}
404+
}
405+
-1
406+
}
407+
}
408+
```
409+
275410
### **Go**
276411

277412
Two-end BFS:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use std::collections::VecDeque;
2+
3+
const DIR: [(i32, i32); 8] = [(-2, 1), (2, 1), (-1, 2), (1, 2), (2, -1), (-2, -1), (1, -2), (-1, -2)];
4+
5+
impl Solution {
6+
#[allow(dead_code)]
7+
pub fn min_knight_moves(x: i32, y: i32) -> i32 {
8+
// The original x, y are from [-300, 300]
9+
// Let's shift them to [0, 600]
10+
let x: i32 = x + 300;
11+
let y: i32 = y + 300;
12+
let mut ret = -1;
13+
let mut vis: Vec<Vec<bool>> = vec![vec![false; 618]; 618];
14+
// <X, Y, Current Steps>
15+
let mut q: VecDeque<(i32, i32, i32)> = VecDeque::new();
16+
17+
q.push_back((300, 300, 0));
18+
19+
while !q.is_empty() {
20+
let (i, j, s) = q.front().unwrap().clone();
21+
q.pop_front();
22+
if i == x && j == y {
23+
ret = s;
24+
break;
25+
}
26+
Self::enqueue(&mut vis, &mut q, i, j, s);
27+
}
28+
29+
ret
30+
}
31+
32+
#[allow(dead_code)]
33+
fn enqueue(vis: &mut Vec<Vec<bool>>, q: &mut VecDeque<(i32, i32, i32)>, i: i32, j: i32, cur_step: i32) {
34+
let next_step = cur_step + 1;
35+
for (dx, dy) in DIR {
36+
let x = i + dx;
37+
let y = j + dy;
38+
if Self::check_bounds(x, y) || vis[x as usize][y as usize] {
39+
// This <X, Y> pair is either out of bound, or has been visited before
40+
// Just ignore this pair
41+
continue;
42+
}
43+
// Otherwise, add the pair to the queue
44+
// Also remember to update the vis vector
45+
vis[x as usize][y as usize] = true;
46+
q.push_back((x, y, next_step));
47+
}
48+
}
49+
50+
#[allow(dead_code)]
51+
fn check_bounds(i: i32, j: i32) -> bool {
52+
i < 0 || i > 600 || j < 0 || j > 600
53+
}
54+
}

0 commit comments

Comments
 (0)