LeetCode 15 sum of three numbers & 16 the closest sum of three numbers

Sum of three numbers (dual pointer)

Question:
Give you an array nums containing n integers, and judge whether there are three elements a, b, c in nums such that a + b + c = 0? Please find all triples that meet the conditions and are not repeated.

Note: The answer cannot contain repeated triples.

Example:

Given the array nums = [-1, 0, 1, 2, -1, -4], the
set of triples that meet the requirements is:
[
[-1, 0, 1],
[-1, -1, 2]
]

Analysis:
From the numerical analysis, a+b+c=0 must have numbers greater than or equal to 0, and some numbers less than or equal to 0. If there is no order, then violently enumerate each number O(n3) and also need to consider deduplication .

You can take a static and dynamic way of thinking. First , sort the sequence . There are three numbers, one on the left, one on the left, one on the right, and one of the three as the fixed point . If the middle is temporary, the left and right are from both sides. Probing to the middle pointer, if it encounters an equal one, join the result set. However, such a result needs to be de-duplicated because it cannot be judged as unique. The specific implementation code is:

public List<List<Integer>> threeSum(int[] nums) {
    
    
          List<List<Integer>> list=new ArrayList<List<Integer>>();
		 Set<String>set=new HashSet<String>();
		 Arrays.sort(nums);
		 
		 for(int i=1;i<nums.length-1;i++)
		 {
    
    	 
			int left=0;int right=nums.length-1;
			
			while (left<i&&right>i) {
    
    
				//System.out.println(i+" "+left+" "+i+" "+right+" "+list.toString());
				if(nums[left]>0)break;
				int sum=nums[left]+nums[i]+nums[right];
				//System.out.println(nums[left]+" "+nums[i]+" "+nums[right]);
				if(sum==0)
				{
    
    
				
					String teamString=nums[left]+" "+nums[i]+" "+nums[right];
					if(!set.contains(teamString)) {
    
    
					List<Integer>list2=new ArrayList<Integer>();
					list2.add(nums[left]);list2.add(nums[i]);list2.add(nums[right]);
					list.add(list2);
					set.add(teamString);
					}
					left++;right--;
				}
				else if (sum>0) {
    
    
					right--;
				}
				else {
    
    
					left++;
				}
			}
			 	 
		 }
		 return list;	 
    }

And if the loop once determines the left , the middle and the right to expand to the right and left respectively, then this can achieve a de-duplication, and the time complexity is O(n2), but the following details need to be paid attention to:

  • If the current leftmost number sums[i] is equal to sums[i-1] (i>1), then jump out of this calculation, because if the current number is the leftmost number, the same number before it can form this set. So there is no need for this calculation .
  • At the same time, when determining the leftmost, middle left and rightmost right to the middle, if the sum of three numbers is greater than 0, then right–; if the sum of three numbers is less than 0, then left++; at the same time, you can perform partial pruning optimization, Directly filter out the impossible.

The ac code is:

 public List<List<Integer>> threeSum(int[] nums) {
    
    
         List<List<Integer>> list=new ArrayList<List<Integer>>();
		 Arrays.sort(nums);
		 for(int i=0;i<nums.length-2;i++)
		 {
    
    	 
			int left=i+1;int right=nums.length-1;
			if(i>0&&nums[i]==nums[i-1])continue;
			while (left<right) {
    
    
				//System.out.println(i+" "+left+" "+i+" "+right+" "+list.toString());
				if(nums[left]+nums[i]>0)break;
				int sum=nums[left]+nums[i]+nums[right];
				//System.out.println(nums[left]+" "+nums[i]+" "+nums[right]);
				if(sum==0)
				{
    
    
					List<Integer>list2=new ArrayList<Integer>();
					list2.add(nums[i]);
					while (left<right&&nums[left]==nums[left+1]) {
    
    left++;}
					list2.add(nums[left]);
					while (left<right&&nums[right]==nums[right-1]) {
    
    right--;}
					list2.add(nums[right]);
					list.add(list2);
					left++;right--;
				} 
				else if (sum>0) {
    
    
					right--;
				}
				else {
    
    
					left++;
				}
			}

	}
	return list;
   }

The nearest sum of three numbers

Question:
Given an array nums including n integers and a target value target. Find the three integers in nums so that their sum is closest to target. Returns the sum of these three numbers. Assume that there is only one answer for each set of inputs.

Example:

Input: nums = [-1,2,1,-4], target = 1
Output: 2
Explanation: The closest sum to target is 2 (-1 + 2 + 1 = 2).

prompt:

3 <= nums.length <= 10^3
-10^3 <= nums[i] <= 10^3
-10^4 <= target <= 10^4

Analysis:
With the idea of ​​the previous question, this question still uses double pointers , but the closest thing to sum requires you to record its size with numbers and also need to consider the issue of positive and negative.

The specific processing is consistent with the overall idea of ​​the previous question. First, sort, loop to determine the leftmost one , this layer is O(n), and at the same time, the middle and right sides of each leftmost determined sum move closer to the middle. If the sum of three numbers is greater than the target, then right–, otherwise left++, and at the same time compare with the closest number to see if it is closer, so that the sum of the three numbers closest to the target can be obtained after execution.

The specific implementation code is:

 public static int threeSumClosest(int[] nums, int target) {
    
    	
	     Arrays.sort(nums);
	     int value=nums[0]+nums[1]+nums[2];
		 for(int i=0;i<nums.length-2;i++)
		 {
    
    	 
			int left=i+1;int right=nums.length-1;
			
			while (left<right) {
    
    
				int sum=nums[left]+nums[i]+nums[right];
				int gap1=Math.abs(value-target);
				int gap2=Math.abs(sum-target);
				 if(target>=0&&nums[left]+nums[i]-target>gap1)break;
				if(gap2<gap1)
				{
    
    
					value=sum;
				} 
			    if (sum==target) {
    
    
					return target;
				}
				else if(sum>target) {
    
    
					right--;
				}
			    else {
    
    
					left++;
				}  
			}
	    }
		 return value;
	 }

Finally, if you check in, please follow and bigsaireply to check in.
Insert picture description here

Guess you like

Origin blog.csdn.net/qq_40693171/article/details/108299163