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
| pub struct Solution {}
impl Solution { pub fn three_sum(nums: Vec<i32>) -> Vec<Vec<i32>> { let len = nums.len(); if len < 3 { return vec![] } let mut nums = nums; nums.sort(); let mut i = 0; let mut result: Vec<Vec<i32>> = Vec::new(); let mut previous = nums[0] - 1; while i < len - 2 { if nums[i] == previous { i += 1; continue; } previous = nums[i]; let vec = Solution::two_sum(&nums[(i+1)..len], 0 - nums[i]); for t in vec.iter() { result.push(vec![nums[i], t.0, t.1]); } i += 1; } result }
#[inline(always)] fn two_sum(nums: &[i32], sum: i32) -> Vec<(i32, i32)> { let (mut i, mut j) = (0_usize, nums.len() - 1); let mut result = Vec::new(); while i < j { if nums[i] + nums[j] < sum { i += 1; } else if nums[i] + nums[j] > sum { j -= 1 } else { result.push((nums[i], nums[j])); i = Solution::next_unique(nums, i, true); j = Solution::next_unique(nums, j, false); } } result }
#[inline(always)] fn next_unique(nums: &[i32], idx: usize, forward: bool) -> usize { let current = nums[idx]; let mut i = idx; while i > 0 && i < nums.len() && nums[i] == current { i = if forward { i + 1 } else { i - 1 } } i } }
#[cfg(test)] mod tests { use super::*;
#[test] fn test_leetcode_15() { assert_eq!(Solution::three_sum(vec![-1, 0, 1, 2, -1, -4]), vec![vec![-1, -1, 2], vec![-1, 0, 1]]); let empty_vec: Vec<Vec<i32>> = vec![]; assert_eq!(Solution::three_sum(vec![]), empty_vec); } }
|