20240629 Finished
This commit is contained in:
parent
7f95c66933
commit
e760e2168a
|
@ -161,3 +161,4 @@ mod p207_course_schedule;
|
||||||
mod p210_course_schedule_ii;
|
mod p210_course_schedule_ii;
|
||||||
mod p909_snakes_and_ladders;
|
mod p909_snakes_and_ladders;
|
||||||
mod p433_minimum_genetic_mutation;
|
mod p433_minimum_genetic_mutation;
|
||||||
|
mod p127_word_ladder;
|
175
src/problem/p127_word_ladder.rs
Normal file
175
src/problem/p127_word_ladder.rs
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
/**
|
||||||
|
* [127] Word Ladder
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn ladder_length(begin_word: String, end_word: String, word_list: Vec<String>) -> i32 {
|
||||||
|
let mut start = usize::MAX;
|
||||||
|
let mut start_found = false;
|
||||||
|
let mut end_found = false;
|
||||||
|
let mut end = usize::MAX;
|
||||||
|
|
||||||
|
for (i, word) in word_list.iter().enumerate() {
|
||||||
|
if *word == begin_word {
|
||||||
|
start_found = true;
|
||||||
|
start = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut neighbors = vec![HashSet::new(); word_list.len()];
|
||||||
|
|
||||||
|
// 构建邻接矩阵
|
||||||
|
for i in 0..word_list.len() {
|
||||||
|
for j in 1..word_list.len() {
|
||||||
|
if Self::is_one_char(&word_list[i], &word_list[j]) {
|
||||||
|
neighbors[i].insert(j);
|
||||||
|
neighbors[j].insert(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if word_list[i] == end_word {
|
||||||
|
end_found = true;
|
||||||
|
end = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !start_found {
|
||||||
|
if Self::is_one_char(&word_list[i], &begin_word) {
|
||||||
|
start = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !end_found {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果开始和结束相同
|
||||||
|
// 则必然是跳了一步
|
||||||
|
if start == end {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut result = i32::MAX;
|
||||||
|
|
||||||
|
// dijkstra算法
|
||||||
|
let mut distances = vec![i32::MAX; word_list.len()];
|
||||||
|
let mut flags = vec![false; word_list.len()];
|
||||||
|
distances[start] = 0;
|
||||||
|
flags[start] = true;
|
||||||
|
for &i in &neighbors[start] {
|
||||||
|
distances[i] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 1..word_list.len() {
|
||||||
|
let mut min = i32::MAX;
|
||||||
|
let mut next = 0;
|
||||||
|
|
||||||
|
for i in 0..word_list.len() {
|
||||||
|
if !flags[i] && distances[i] < min {
|
||||||
|
min = distances[i];
|
||||||
|
next = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flags[next] = true;
|
||||||
|
if next == end {
|
||||||
|
result = result.min(min);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for &i in &neighbors[next] {
|
||||||
|
if !flags[i] && min + 1 < distances[i] {
|
||||||
|
distances[i] = min + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if result == i32::MAX {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
if start_found {
|
||||||
|
result + 1
|
||||||
|
} else {
|
||||||
|
result + 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_one_char(a: &String, b: &String) -> bool {
|
||||||
|
let mut one_char = false;
|
||||||
|
|
||||||
|
for (c1, c2) in a.chars().zip(b.chars()) {
|
||||||
|
if c1 != c2 {
|
||||||
|
if one_char {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
one_char = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
one_char
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_127() {
|
||||||
|
assert_eq!(
|
||||||
|
Solution::ladder_length(
|
||||||
|
"hit".to_owned(),
|
||||||
|
"cog".to_owned(),
|
||||||
|
vec![
|
||||||
|
"hot".to_owned(),
|
||||||
|
"dot".to_owned(),
|
||||||
|
"dog".to_owned(),
|
||||||
|
"lot".to_owned(),
|
||||||
|
"log".to_owned(),
|
||||||
|
"cog".to_owned()
|
||||||
|
]
|
||||||
|
),
|
||||||
|
5
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(Solution::ladder_length("a".to_owned(), "c".to_owned(), vec![
|
||||||
|
"a".to_owned(),
|
||||||
|
"b".to_owned(),
|
||||||
|
"c".to_owned()
|
||||||
|
]), 2);
|
||||||
|
|
||||||
|
assert_eq!(Solution::ladder_length("a".to_owned(), "c".to_owned(), vec![
|
||||||
|
"c".to_owned()
|
||||||
|
]), 2);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Solution::ladder_length(
|
||||||
|
"hot".to_owned(),
|
||||||
|
"dog".to_owned(),
|
||||||
|
vec![
|
||||||
|
"hot".to_owned(),
|
||||||
|
"dot".to_owned(),
|
||||||
|
"dog".to_owned(),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
3
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(Solution::ladder_length("lost".to_owned(), "cost".to_owned(), vec![
|
||||||
|
"most".to_owned(),
|
||||||
|
"fist".to_owned(),
|
||||||
|
"lost".to_owned(),
|
||||||
|
"cost".to_owned(),
|
||||||
|
"fish".to_owned()
|
||||||
|
]), 2);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user