3Sum (Medium) description

Given an array `nums`

of n integers, is 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.

**Note:**

The solution set must not contain duplicate triplets.

**Example:**

`Given array nums = [-1, 0, 1, 2, -1, -4],A solution set is:[ [-1, 0, 1], [-1, -1, 2]]`

Analysis

The first is the most easily thought of brute force, by iterating through the array `nums`

, sequentially determining, and `nums[i]`

calculating whether the sum of the `nums[j]`

ternary is `nums[k]`

0. This is the most brutal solution, but there are problems of de-weight, such as [-1, 0, 1] and [0, 1,-1] this situation.

Secondly, this topic as the advanced topic of 2Sum, it is easy to think of the 3Sum into the target value for `0 - nums[i]`

, and in the remaining elements of the array to find the sum of two elements of the target 2Sum problem. But there is also the problem of de-weight.

About to go to the heavy because it's a list

Finally, the above two ideas have a problem of de-weight, the problem is to find out the array of three elements of the sum of 0 of all combinations. The de-emphasis process is obviously unrelated to the result, but it is very cumbersome, so it is important to optimize the algorithm to remove the weight of this step.

It's time to be aware of the border problem when it comes to brute force.

You can write this in the first layer of the loop: `for(int i = 0; i < nums.length - 2; i++)`

. That is, the end condition of the first layer loop is `nums.length - 2`

that it does not need to be `nums.length`

.

Same as the second layer loop: `for(int j = i + 1; j < nums.length - 1; j++)`

. The start index does not need to start at 0, and can be done directly from `i + 1`

the beginning `nums.length - 1`

.

The third layer: `for(int k = j + 1; k < nums.length; k++)`

.

We can see that at the time of brute force, we have consciously filtered out some conditions by boundary conditions, and we have made a preliminary optimization. Notice that the array itself is unordered, so it is difficult to define whether the current traversal element has been selected when determining the element. If the array is ordered, then the triple traversal can consciously skip repeating elements. It has been optimized to solve the problem of brute force, but the triple traversal is undoubtedly the result of the time Complexity O (n^3), so high time complexity must be discarded. So how do you continue to optimize it?

Try to optimize the idea two. First use sorting to solve the problem of de-weight. Iterate through the sorted array, fix the first element as `nums[i]`

, and then `i + 1`

`nums.length`

find two elements between the index bits and `nums[j]`

`nums[k]`

the sum of `0 - nums[i]`

the two. Although this can do the traversal twice to achieve the goal, I believe that basically 2Sum is done this way. But for an ordered array, the clamping method can reduce the time complexity of the process to O (N). Therefore, the clamping method is used to find the remaining two elements. PS, do not forget the 2Sum using the clamping method to optimize.

Code

`Public list<list<integer>> threesum (int[] nums) {list<list<integer>> result = new LINKEDLIST&L T List<integer>> (); if (nums = = NULL | | Nums.length < 3) {return result; }//Array sort arrays.sort (nums); Fixed first element nums[i] for (int i = 0; i < nums.length-2; i++) {//default is from small to large, so when nums[i] is greater than 0, you can end if (n Ums[i] > 0) {break; }//nums[i-1]! = nums[i] performed the de-weight, notice here in understanding that the array of operations at this time is already an ordered array if (i = = 0 | | nums[i-1]! = Nums[i]) { Using the Add force method Int J = i + 1; int k = nums.length-1; while (J < k) {int sum = Nums[i] + nums[j] + nums[k]; if (sum = = 0) {result.add (Arrays.aslist (Nums[i], nums[j], nums[k])); } if (sum <= 0) {while (J < k && Nums[j] = = Nums[++j]); } if (sum >= 0) {WHILe (J < k && Nums[k] = = Nums[--k]); }}}} return result;`

The above code is optimized after the code, for the understanding of the process of forcing a little inconvenience, the following is the original wording of the addition force:

`while (j < k) { int target = 0 - nums[i]; if(target == (nums[j] + nums[k])){ result.add(Arrays.asList(nums[i], nums[j], nums[k])); j++; while(nums[j] == nums[j - 1] && j < k){ //去重，注意这是一个有序数组 j++; } k--; while(nums[k] == nums[k + 1] && j < k){ //去重，注意这是一个有序数组 k--; } }else if(target < (nums[j] + nums[k])){ k--; while(nums[k] == nums[k + 1] && j < k){ k--; } }else if(target > (nums[j] + nums[k])){ j++; while(nums[j] == nums[j - 1] && j < k){ j++; } } }`

Leetcode of the 15. 3Sum (Medium)