Leetcode the sum of two numbers, three numbers and four numbers


Leetcode Two Number Sum, Three Number Sum, Four Number Sum Trilogy

1. the sum of two numbers

1.1 Title description

Given an integer array nums and a target value target, please find the two integers whose sum is the target value in the array and return their array subscripts .

You can assume that each input will only correspond to one answer. However, you cannot reuse the same elements in this array.

Example:

Given nums = [2, 7, 11, 15], target = 9

Because nums[0] + nums[1] = 2 + 7 = 9,
it returns [0, 1]

1.2 Problem solving ideas

It's very simple, it is to traverse the two levels and find the two numbers whose sum is equal to the target value.
Hold down one pointer i, the other pointer j moves, one by one goes away...

1.3 Java code

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int len = nums.length;
        int[] results = new int[2];
        for(int i =0;i<len;i++){
            for(int j = i+1;j<len;j++){
                if(nums[i]+nums[j] == target){
                    results[0] = i;
                    results[1] = j;
                    return results;
                }
            }
        }
        return null;
    }
}

2. Sansanowa

2.1 Title description

Given an array nums containing n integers, determine whether there are three elements a, b, c in nums such that a + b + c = 0? Find all triples that meet the conditions and are not repeated.

Note: The answer cannot contain repeated triples.

For example, given the array nums = [-1, 0, 1, 2, -1, -4],

The set of triples that meet the requirements are:
[
[-1, 0, 1],
[-1, -1, 2]
]

2.2 Problem-solving ideas

It's a bit difficult to introduce. The trouble is the handling of duplicate values. The most straightforward idea is to continue the traversal of the sum of two numbers. Isn't it enough to traverse three levels? But... It really doesn't work. Even if it is troublesome to deal with duplicate values, the special situation (three numbers are equal) is also taken into account, and finally...timeout!

I can only find another way: use the idea of ​​moving the left and right pointers to the middle, and continue to move if they encounter the same thing, that is, skip the repeated elements.
Since it moves like this, the repeated elements are required to be next to each other. How to make the repeating elements next to each other?
Sort!
Therefore, sort first, which is also the general practice of arrays. The advantage of sorting is also: you can move the left and right pointers according to the size of the current sum.
In short, sort first. Fix a value again and convert the sum of three numbers into the sum of two numbers. That is, nums[i]+nums[j]+nums[k] = 0 is converted to nums[i]+nums[j] = 0-nums[k]

When i moves, you can also skip the repeated elements, that is, in the codeif(i>0&&nums[i] == nums[i-1]) continue;//略过重复元素

The left and right pointers point to the next element and the last element of i respectively:

int left = i+1;
int right = len-1;

When a number that satisfies the condition is found, it is added to the result set. And move the left and right pointers until an element is not equal to the current element (ignore the repeated elements).

while(left<right&&nums[left]==nums[left+1]){
	left++;
}
while(left<right&&nums[right]==nums[right-1]){
	right--;
}
left++;
right--;

If the sum is greater than the target, the right pointer moves left; otherwise, the left pointer moves right.

2.3 Java code

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        // 先排序
		int len = nums.length;
		Arrays.sort(nums);
		List<List<Integer>> results = new ArrayList<>();
		for(int i = 0;i<len;i++){
			if(i>0&&nums[i] == nums[i-1]) continue;//略过重复元素
			int left = i+1;
			int right = len-1;
			int newTarget = 0 - nums[i];
			while(left<right){
				if(nums[left]+nums[right] == newTarget){
					List<Integer> temp = new ArrayList<>();
					temp.add(nums[i]);
					temp.add(nums[left]);
					temp.add(nums[right]);
					results.add(temp);
					while(left<right&&nums[left]==nums[left+1]){
						left++;
					}
					while(left<right&&nums[right]==nums[right-1]){
						right--;
					}
					left++;
					right--;
				}else if(nums[left]+nums[right] > newTarget){
					right--;
				}else{
					left++;
				}
			}
		}
		
		return results;
    }
}

3. The sum of four numbers

3.1 Title description

Given an array nums containing n integers and a target value target, judge whether there are four elements a, b, c, and d in nums so that the value of a + b + c + d is equal to target? Find all four-tuples that meet the conditions and do not repeat.

note:

The answer cannot contain repeated quadruples.

Example:

Given the array nums = [1, 0, -1, 0, -2, 2], and target = 0.

The set of quadruples that meet the requirements are:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]

3.2 Problem-solving ideas

Similar to the sum of three numbers. First transform the sum of four numbers into the sum of three numbers, and then transform the sum of three numbers into the sum of two numbers.
Once you have mastered this, the sum of five numbers, six numbers... is no longer afraid, it's all a routine, just a few more cycles.

3.3 Java code

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> results = new ArrayList<>();
        int len = nums.length;
        //排序
        Arrays.sort(nums);
        for(int i = 0;i<len;i++){
            if(i>0&&nums[i] == nums[i-1]) continue;
            int newTarget1 = target-nums[i];//将四数之和转为三数之和
            for(int j = i+1;j<len;j++){
                if(j>i+1&&nums[j] == nums[j-1]) continue;
                int newTarget2 = newTarget1-nums[j];//将三数之和转为两数之和
                int left = j+1;
                int right = len-1;
                while(left<right){
                    if(nums[left]+nums[right] == newTarget2){
                        List<Integer> temp = new ArrayList<>();
						temp.add(nums[i]);
                        temp.add(nums[j]);
						temp.add(nums[left]);
						temp.add(nums[right]);
						results.add(temp);
                        //跳过重复元素
                        while(left<right&&nums[left] == nums[left+1]) left++;
                        while(left<right&&nums[right] == nums[right-1]) right--;
                        left++;
                        right--;
                    }else if(nums[left]+nums[right] > newTarget2){
                        right--;
                    }else{
                        left++;
                    }
                }
             
            }
        }
        return results;
        
        
    }
}

PS: Note that the "sum of two numbers" requires the return of the element's subscript , and the latter two require the return of the element value. This is also one of the reasons why the first question cannot be sorted, because it is simple, and it is not necessary. Sort.

Guess you like

Origin blog.csdn.net/fxjzzyo/article/details/87369550