Skip to content

Commit cf546bd

Browse files
Improve Two Sum example (rust-lang#365)
1 parent 7619697 commit cf546bd

File tree

1 file changed

+47
-21
lines changed

1 file changed

+47
-21
lines changed

src/general/two_sum.rs

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,47 @@
11
use std::collections::HashMap;
2-
use std::convert::TryInto;
3-
4-
// Given an array of integers nums and an integer target,
5-
// return indices of the two numbers such that they add up to target.
6-
7-
pub fn two_sum(nums: Vec<i32>, target: i32) -> Vec<i32> {
8-
let mut hash_map: HashMap<i32, i32> = HashMap::new();
9-
10-
for (i, item) in nums.iter().enumerate() {
11-
match hash_map.get(&(target - item)) {
12-
Some(value) => {
13-
return vec![i.try_into().unwrap(), *value];
14-
}
15-
None => {
16-
hash_map.insert(*item, i.try_into().unwrap());
17-
}
18-
}
2+
3+
/// Given an array of integers nums and an integer target,
4+
/// return indices of the two numbers such that they add up to target.
5+
///
6+
/// # Parameters
7+
///
8+
/// - `nums`: A list of numbers to check.
9+
/// - `target`: The target sum.
10+
///
11+
/// # Returns
12+
///
13+
/// If the target sum is found in the array, the indices of the augend and
14+
/// addend are returned as a tuple.
15+
///
16+
/// If the target sum cannot be found in the array, `None` is returned.
17+
///
18+
pub fn two_sum(nums: Vec<i32>, target: i32) -> Option<(usize, usize)> {
19+
// This HashMap is used to look up a corresponding index in the `nums` list.
20+
// Given that we know where we are at in the array, we can look up our
21+
// complementary value using this table and only go through the list once.
22+
//
23+
// We populate this table with distances from the target. As we go through
24+
// the list, a distance is computed like so:
25+
//
26+
// `target - current_value`
27+
//
28+
// This distance also tells us about the complementary value we're looking
29+
// for in the array. If we don't find that value, we insert `current_value`
30+
// into the table for future look-ups. As we iterate through the list,
31+
// the number we just inserted might be the perfect distance for another
32+
// number, and we've found a match!
33+
//
34+
let mut distance_table: HashMap<i32, usize> = HashMap::new();
35+
36+
for (i, current_value) in nums.iter().enumerate() {
37+
match distance_table.get(&(target - current_value)) {
38+
Some(j) => return Some((i, *j)),
39+
_ => distance_table.insert(*current_value, i),
40+
};
1941
}
2042

21-
vec![]
43+
// No match was found!
44+
None
2245
}
2346

2447
#[cfg(test)]
@@ -28,12 +51,15 @@ mod test {
2851
#[test]
2952
fn test() {
3053
let nums = vec![2, 7, 11, 15];
31-
assert_eq!(two_sum(nums, 9), vec![1, 0]);
54+
assert_eq!(two_sum(nums, 9), Some((1, 0)));
3255

3356
let nums = vec![3, 2, 4];
34-
assert_eq!(two_sum(nums, 6), vec![2, 1]);
57+
assert_eq!(two_sum(nums, 6), Some((2, 1)));
3558

3659
let nums = vec![3, 3];
37-
assert_eq!(two_sum(nums, 6), vec![1, 0]);
60+
assert_eq!(two_sum(nums, 6), Some((1, 0)));
61+
62+
let nums = vec![2, 7, 11, 15];
63+
assert_eq!(two_sum(nums, 16), None);
3864
}
3965
}

0 commit comments

Comments
 (0)