11M
2- 1516696879
2+ 1533626601
33tags : Hash Table
44
55#### Based on 2 sum
@@ -44,26 +44,25 @@ Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b
44442nd part: try [i + 1, end], see if any combination sum that makes: target - sum exist in map. -> becomes same old 2sum problem.
4545O(n)
4646*/
47- /*
48- Thoughts:
49- Can't do for loop over 3sum, which is O(n^3), not doable.
50- We can break the nums into 2 major parts by index i.
51- 1st part: from [0 ~ i], we'll try all possible ways to pair [x, i] and store the sum of nums[x]+nums[i] in map.
52- Note: key is sum, and the value is a hashSet of ArrayList. Where the hashset has itself functions to tell duplicate of pairs.
53- 2nd part: try [i + 1, end], see if any combination sum that makes: target - sum exist in map. -> becomes same old 2sum problem.
47+ /**
48+ Why having below front-pair-building after previous for end-pair-checking for loop?
49+ Here: we build [0 ~ i], and in next round, when we processs [i + 1, end], pairs built among [0~i] below will all be used.
50+ Rather: if we have lift the for loop below to calculate [0~i] before the end-pair-checking of same [i~end],
51+ there is one index at [i] will overlap, which turns to be incorrect.
52+ Therefore, we build front-pairs aftwarwards: it's building [0~i] here, which aims to help next round of end-pair-checking on [i+1, end].
5453*/
5554class Solution {
5655 public List <List <Integer >> fourSum (int [] nums , int target ) {
5756 List <List <Integer >> result = new ArrayList <>();
58- if (nums == null || nums .length <= 3 ) {
59- return result ;
60- }
57+ if (nums == null || nums .length <= 3 ) return result ;
58+
59+ int n = nums . length ;
6160 Arrays .sort (nums );
6261 Map <Integer , HashSet <List >> map = new HashMap <>();
6362 Set <String > cache = new HashSet <>();
64- for (int i = 0 ; i < nums . length ; i ++) {
63+ for (int i = 0 ; i < n ; i ++) {
6564 // Check if [i + 1, end] can be added up to target
66- for (int k = i + 1 ; k < nums . length ; k ++) {
65+ for (int k = i + 1 ; k < n ; k ++) {
6766 int sum = nums [i ] + nums [k ];
6867 if (map .containsKey (target - sum )) {// Try to match up the 4 pairs
6968 for (List <Integer > frontPair : map .get (target - sum )) {
@@ -76,19 +75,11 @@ public List<List<Integer>> fourSum(int[] nums, int target) {
7675 }
7776 }
7877 }
79- /**
80- Why having below front-pair-building after previous for end-pair-checking for loop?
81- Here: we build [0 ~ i], and in next round, when we processs [i + 1, end], pairs built among [0~i] below will all be used.
82- Rather: if we have lift the for loop below to calculate [0~i] before the end-pair-checking of same [i~end],
83- there is one index at [i] will overlap, which turns to be incorrect.
84- Therefore, we build front-pairs aftwarwards: it's building [0~i] here, which aims to help next round of end-pair-checking on [i+1, end].
85- */
78+
8679 // Build up the pair from [0 ~ i]
8780 for (int j = 0 ; j < i ; j ++) {
8881 int sum = nums [j ] + nums [i ];
89- if (!map .containsKey (sum )) {
90- map .put (sum , new HashSet <>());
91- }
82+ map .putIfAbsent (sum , new HashSet <>());
9283 map .get (sum ).add (Arrays .asList (nums [j ], nums [i ]));
9384 }
9485 }
@@ -101,6 +92,9 @@ private String buildKey(List<Integer> list) {
10192 return sb .toString ();
10293 }
10394}
95+
96+
97+
10498/*
10599Thoughts
106100Perform another layer outside of 3SUM. O(n^3).
0 commit comments