Skip to content

Commit df2f1b8

Browse files
committed
solve #127
1 parent 7842317 commit df2f1b8

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,4 @@ mod n0123_best_time_to_buy_and_sell_stock_iii;
125125
mod n0124_binary_tree_maximum_path_sum;
126126
mod n0125_valid_palindrome;
127127
mod n0126_word_ladder_ii;
128+
mod n0127_word_ladder;

src/n0127_word_ladder.rs

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/**
2+
* [127] Word Ladder
3+
*
4+
* Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:
5+
*
6+
* <ol>
7+
* Only one letter can be changed at a time.
8+
* Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
9+
* </ol>
10+
*
11+
* Note:
12+
*
13+
*
14+
* Return 0 if there is no such transformation sequence.
15+
* All words have the same length.
16+
* All words contain only lowercase alphabetic characters.
17+
* You may assume no duplicates in the word list.
18+
* You may assume beginWord and endWord are non-empty and are not the same.
19+
*
20+
*
21+
* Example 1:
22+
*
23+
*
24+
* Input:
25+
* beginWord = "hit",
26+
* endWord = "cog",
27+
* wordList = ["hot","dot","dog","lot","log","cog"]
28+
*
29+
* Output: 5
30+
*
31+
* Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
32+
* return its length 5.
33+
*
34+
*
35+
* Example 2:
36+
*
37+
*
38+
* Input:
39+
* beginWord = "hit"
40+
* endWord = "cog"
41+
* wordList = ["hot","dot","dog","lot","log"]
42+
*
43+
* Output: 0
44+
*
45+
* Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.
46+
*
47+
*/
48+
pub struct Solution {}
49+
50+
// submission codes start here
51+
52+
use std::collections::VecDeque;
53+
use std::collections::HashSet;
54+
impl Solution {
55+
pub fn ladder_length(begin_word: String, end_word: String, word_list: Vec<String>) -> i32 {
56+
let len = word_list.len();
57+
let target = word_list.iter().position(|s| s == &end_word);
58+
if target.is_none() { return 0 }
59+
let target = target.unwrap();
60+
let mut deq = VecDeque::new();
61+
let mut distance = vec![0; len];
62+
let mut remain = (0..len).collect::<HashSet<_>>();
63+
deq.push_back(target);
64+
remain.remove(&target);
65+
while let Some(i) = deq.pop_front() {
66+
if Solution::connect(&begin_word, &word_list[i]) {
67+
return distance[i] + 2;
68+
}
69+
remain.retain(|&j| {
70+
if Solution::connect(&word_list[i], &word_list[j]) {
71+
distance[j] = distance[i] + 1;
72+
deq.push_back(j);
73+
false
74+
} else {
75+
true
76+
}
77+
});
78+
}
79+
0
80+
}
81+
82+
#[inline(always)]
83+
fn connect(s1: &str, s2: &str) -> bool {
84+
if s1.len() != s2.len() { return false }
85+
let mut iter1 = s1.chars().into_iter();
86+
let mut iter2 = s2.chars().into_iter();
87+
let mut diff = 0;
88+
while let (Some(c1), Some(c2)) = (iter1.next(), iter2.next()) {
89+
if c1 != c2 {
90+
diff += 1;
91+
if diff >= 2 { return false }
92+
}
93+
}
94+
true
95+
}
96+
}
97+
98+
// submission codes end
99+
100+
#[cfg(test)]
101+
mod tests {
102+
use super::*;
103+
104+
#[test]
105+
fn test_127() {
106+
assert_eq!(
107+
Solution::ladder_length("hit".to_owned(), "cog".to_owned(),
108+
vec_string!["hot","dot","dog","lot","log","cog"]),
109+
5
110+
);
111+
assert_eq!(
112+
Solution::ladder_length("hit".to_owned(), "cog".to_owned(),
113+
vec_string!["hot","dot","dog","lot","log"]),
114+
0
115+
);
116+
}
117+
}

0 commit comments

Comments
 (0)