Skip to content

Commit 121b736

Browse files
committed
solve aylei#18
1 parent ceafaa5 commit 121b736

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ mod n0014_longest_common_prefix;
1515
mod n0015_3sum;
1616
mod n0016_3sum_closest;
1717
mod n0017_letter_combinations_of_a_phone_number;
18+
mod n0018_4sum;

src/n0018_4sum.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/**
2+
* [18] 4Sum
3+
*
4+
* Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
5+
*
6+
* Note:
7+
*
8+
* The solution set must not contain duplicate quadruplets.
9+
*
10+
* Example:
11+
*
12+
*
13+
* Given array nums = [1, 0, -1, 0, -2, 2], and target = 0.
14+
*
15+
* A solution set is:
16+
* [
17+
* [-1, 0, 0, 1],
18+
* [-2, -1, 1, 2],
19+
* [-2, 0, 0, 2]
20+
* ]
21+
*
22+
*
23+
*/
24+
pub struct Solution {}
25+
26+
// submission codes start here
27+
28+
// TODO: change to faster N^3 solution... maybe
29+
// this is a N^2 * logN solution, but slower than N^3 solution
30+
// iterate all combinations and the sum of 2 elements, then use one-round hash
31+
use std::collections::BTreeMap;
32+
use std::collections::HashSet;
33+
impl Solution {
34+
pub fn four_sum(nums: Vec<i32>, target: i32) -> Vec<Vec<i32>> {
35+
if nums.len() < 4 { return vec![] }
36+
let mut set: HashSet<Vec<i32>> = HashSet::new();
37+
let mut map: BTreeMap<i32, Vec<(usize, usize)>> = BTreeMap::new();
38+
// collect two-sums in asc order, store the index to avoid single number reusing
39+
for i in 0..(nums.len() - 1) {
40+
for j in (i + 1)..nums.len() {
41+
map.entry(nums[i] + nums[j]).or_insert(Vec::new()).push((i, j));
42+
}
43+
}
44+
// find results
45+
for (&sum, pairs) in map.iter() {
46+
// avoid duplicates
47+
if sum > target / 2 { break; }
48+
match map.get(&(target - sum)) {
49+
None => continue,
50+
// 2-sum + 2-sum == target, then all the possible combination
51+
// (without index conflicts) is our answer
52+
Some(subs) => {
53+
for pair in pairs.iter() {
54+
for sub in subs.iter() {
55+
if sub.0 == pair.0 || sub.0 == pair.1 || sub.1 == pair.0 || sub.1 == pair.1 {
56+
continue
57+
}
58+
let mut vec = vec![nums[pair.0], nums[pair.1], nums[sub.0], nums[sub.1]];
59+
vec.sort();
60+
set.insert(vec);
61+
}
62+
}
63+
}
64+
}
65+
}
66+
set.into_iter().collect()
67+
}
68+
}
69+
70+
// submission codes end
71+
72+
#[cfg(test)]
73+
mod tests {
74+
use super::*;
75+
76+
#[test]
77+
fn test_18() {
78+
assert_eq!(Solution::four_sum(vec![1, 0, -1, 0, -2, 2], 0), vec![
79+
vec![-1, 0, 0, 1],
80+
vec![-2, 0, 0, 2],
81+
vec![-2, -1, 1, 2]
82+
]);
83+
}
84+
}

0 commit comments

Comments
 (0)