-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlib.rs
77 lines (66 loc) · 2.39 KB
/
lib.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
/*!
* # 72. Edit Distance
*
* [Problem link](https://leetcode.com/problems/edit-distance/)
*/
#![allow(dead_code)]
struct Solution {}
// ----------------------------------------------------------------------------
use std::collections::HashMap;
impl Solution {
pub fn reduce_min_distance(
word1: &str,
word2: &str,
cache: &mut HashMap<(String, String), usize>,
) -> usize {
if let Some(&min) = cache.get(&(word1.to_string(), word2.to_string())) {
return min;
};
let (length1, length2) = (word1.len(), word2.len());
if length1 == 0 || length2 == 0 {
let min = length1.max(length2);
cache.insert((word1.to_string(), word2.to_string()), min);
return min;
}
let word1_slice = word1[1..].to_string();
let word2_slice = word2[1..].to_string();
if word1.chars().next().unwrap() == word2.chars().next().unwrap() {
return Solution::reduce_min_distance(&word1_slice, &word2_slice, cache);
}
let insert = 1 + Solution::reduce_min_distance(word1, &word2_slice, cache); // insert the first char of word2 in front of word1
let delete = 1 + Solution::reduce_min_distance(&word1_slice, word2, cache); // delete the first char of word1
let edit = 1 + Solution::reduce_min_distance(&word1_slice, &word2_slice, cache); // change from the first char of word1 to the one of word2
let min = *[insert, delete, edit].iter().min().unwrap();
cache.insert((word1.to_string(), word2.to_string()), min);
min
}
pub fn min_distance(word1: String, word2: String) -> i32 {
let mut cache = HashMap::new();
Self::reduce_min_distance(&word1, &word2, &mut cache) as i32
}
}
// ----------------------------------------------------------------------------
#[cfg(test)]
mod tests {
use super::*;
fn accept(word1: &str, word2: &str, expected: i32) {
assert_eq!(
Solution::min_distance(word1.to_string(), word2.to_string()),
expected
);
}
#[test]
fn test_example_1() {
let word1 = "horse";
let word2 = "ros";
let expected = 3;
accept(word1, word2, expected);
}
#[test]
fn test_example_2() {
let word1 = "intention";
let word2 = "execution";
let expected = 5;
accept(word1, word2, expected);
}
}