Skip to content

Commit cbfd5ac

Browse files
committed
solve aylei#15
1 parent 633b7dc commit cbfd5ac

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ mod n0011_container_with_most_water;
1212
mod n0012_integer_to_roman;
1313
mod n0013_roman_to_integer;
1414
mod n0014_longest_common_prefix;
15+
mod n0015_3sum;

src/n0015_3sum.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/**
2+
* [15] 3Sum
3+
*
4+
* Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
5+
*
6+
* Note:
7+
*
8+
* The solution set must not contain duplicate triplets.
9+
*
10+
* Example:
11+
*
12+
*
13+
* Given array nums = [-1, 0, 1, 2, -1, -4],
14+
*
15+
* A solution set is:
16+
* [
17+
* [-1, 0, 1],
18+
* [-1, -1, 2]
19+
* ]
20+
*
21+
*
22+
*/
23+
pub struct Solution {}
24+
25+
// submission codes start here
26+
27+
impl Solution {
28+
pub fn three_sum(nums: Vec<i32>) -> Vec<Vec<i32>> {
29+
let len = nums.len();
30+
if len < 3 { return vec![] }
31+
let mut nums = nums;
32+
nums.sort();
33+
let mut i = 0;
34+
let mut result: Vec<Vec<i32>> = Vec::new();
35+
let mut previous = nums[0] - 1;
36+
while i < len - 2 {
37+
// skip same number
38+
if nums[i] == previous { i += 1; continue }
39+
previous = nums[i];
40+
let mut vec = Solution::two_sum(&nums[(i+1)..len], 0 - nums[i]);
41+
for t in vec.iter() {
42+
result.push(vec![nums[i], t.0, t.1]);
43+
}
44+
i += 1;
45+
}
46+
result
47+
}
48+
49+
// 2 sum using 2 pointers: nums[0] -> <- nums[len-1]
50+
#[inline(always)]
51+
fn two_sum(nums: &[i32], sum: i32) -> Vec<(i32, i32)> {
52+
let (mut i, mut j) = (0_usize, nums.len() - 1);
53+
let mut result = Vec::new();
54+
while i < j {
55+
if nums[i] + nums[j] < sum { i += 1 }
56+
else if nums[i] + nums[j] > sum { j -= 1 }
57+
else {
58+
result.push((nums[i], nums[j]));
59+
i = Solution::next_unique(nums, i, true);
60+
j = Solution::next_unique(nums, j, false);
61+
}
62+
}
63+
result
64+
}
65+
66+
// seek next un-repeat number
67+
#[inline(always)]
68+
fn next_unique(nums: &[i32], idx: usize, forward: bool) -> usize {
69+
let curr = nums[idx];
70+
let mut i = idx;
71+
while i > 0 && i < nums.len() && nums[i] == curr {
72+
i = if forward { i + 1 } else { i - 1 }
73+
}
74+
i
75+
}
76+
}
77+
78+
// submission codes end
79+
80+
#[cfg(test)]
81+
mod tests {
82+
use super::*;
83+
84+
#[test]
85+
fn test_15() {
86+
assert_eq!(Solution::three_sum(vec![-1, 0, 1, 2, -1, -4]), vec![vec![-1, -1, 2], vec![-1, 0, 1]]);
87+
assert_eq!(Solution::three_sum(
88+
vec![-7,-4,-6,6,4,-6,-9,-10,-7,5,3,-1,-5,8,-1,-2,-8,-1,5,-3,-5,4,2,-5,-4,4,7]),
89+
vec![vec![-10,2,8],vec![-10,3,7],vec![-10,4,6],vec![-10,5,5],vec![-9,2,7],vec![-9,3,6],vec![-9,4,5],vec![-8,2,6],vec![-8,3,5],vec![-8,4,4],vec![-7,-1,8],vec![-7,2,5],vec![-7,3,4],vec![-6,-2,8],vec![-6,-1,7],vec![-6,2,4],vec![-5,-3,8],vec![-5,-2,7],vec![-5,-1,6],vec![-5,2,3],vec![-4,-4,8],vec![-4,-3,7],vec![-4,-2,6],vec![-4,-1,5],vec![-3,-2,5],vec![-3,-1,4],vec![-2,-1,3],vec![-1,-1,2]]
90+
);
91+
assert_eq!(Solution::three_sum(vec![2,0,-2,-5,-5,-3,2,-4]),
92+
vec![vec![-4, 2, 2], vec![-2, 0, 2]]);
93+
let empty_vec: Vec<Vec<i32>> = vec![];
94+
assert_eq!(Solution::three_sum(vec![]), empty_vec);
95+
}
96+
}

0 commit comments

Comments
 (0)