Involved in the Dachang series of LeetCode brushing notes: the sum of three numbers (medium)

Learn the algorithm, brush the force button, refuel the roll, enter the big factory!

Topic description

Link to topic

Given an array nums containing n integers, determine whether there are three elements a, b, c in nums such that a + b + c = 0? Please find all triples whose sum is 0 and does not repeat.

Note: Answers cannot contain duplicate triples.

Example 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

Example 2:

输入:nums = []
输出:[]

Example 3:

输入:nums = [0]
输出:[]

hint:

  • 0 <= nums.length <= 3000
  • -105 <= nums[i] <= 105

Involving knowledge points

This is a moderately difficult question, but the idea is relatively simple. The first thing that comes to mind is the brute force solution, but it is obvious that the brute force solution of the three for loop is time-out, and its time complexity is O(n³). But the idea is correct, we can optimize this to reduce its time complexity. The first method is to use the hash table method, which is to sort first, then use two for loops to find the sum of the two elements, and then use the hash table for the remaining elements to determine whether there is this value (note that The second method is the double pointer method, that is, the array is first sorted, and then the movement of the double pointer is used to find the value that satisfies the condition.

Based on the above analysis, the knowledge points we need to know are as follows:

  • An array is a collection of data of the same type stored in a contiguous memory space
  • Array subscripts start from 0
  • The addresses of the array in the memory space are contiguous
  • The array is a simple hash table, where the key in the hash table is the index subscript of the array
  • Hash table can directly access data based on key
  • The contains in HashSet can determine whether there is this value in the hash table

Then according to the title, we can extract the key points:

  • triples whose sum is 0 and does not repeat

Question answer

Java Problem Solution 1

Thought analysis

First, we use the hash table method, that is, sort first, then use two for loops to find the sum of the two elements, and then use the hash table for the remaining elements to determine whether there is this value (pay attention to deduplication )

  • Sort array elements
  • Then use a double for loop to remove duplicate tuples
  • Join the set that meets the conditions
class Solution {
    
    
    public List<List<Integer>> threeSum(int[] nums) {
    
    

       //处理特殊情况
      if(nums.length<3) 
        return new ArrayList<List<Integer>>();//实例化只需要最外层指定具体实现集合类

      List<List<Integer>> res = new ArrayList<List<Integer>>();//初始化结果集合

      Arrays.sort(nums); //排序
       for(int i=0;i<nums.length;i++){
    
    
            if(i>0 && nums[i]==nums[i-1])
                continue; //去掉重复元组
            int target = -nums[i];
            HashSet<Integer> set = new HashSet<Integer>(); //集合来判断是否满足条件
            for(int j=i+1;j<nums.length;) {
    
    
                //如果存在元素满足条件,执行以下逻辑
                if(set.contains(target-nums[j])){
    
    
                    ArrayList<Integer> tmp = new ArrayList<Integer>();
                    tmp.add(nums[i]);
                    tmp.add(nums[j]);
                    tmp.add(target-nums[j]);
                    res.add(tmp);
                    //如果寻找到解,那么不需要将nums[j]加入set,因为此时已经将nums[j]作为答案赋值给res了,nums[j]已经不可能和其他元素搭配组成答案了。
                    //寻找到一个解,如果下一个元素值和当前值一样,那么会出现一个重复的答案,所以直接跳过,直到出现不一样的元素
                    j++;
                    while(j<nums.length&&nums[j]==nums[j-1]){
    
    
                        j++;
                    }
                }else{
    
    
                    //如果当前元素不存在,同时也不满足解条件,那么将当前元素加入set
                    set.add(nums[j++]);
                }
            }
        }
            return res;

    }
}

insert image description here

Java problem solution two

Thought analysis

The second method is the double pointer method, that is, the array is first sorted, and then the movement of the double pointer is used to find the value that satisfies the condition. The specific ideas are as follows:

  • Sort first for easy deduplication
  • Then define the first fixed pointer k to implement traversal
  • Then there are the left and right pointers i and j of the double pointer, the left pointer i is behind k, and the right pointer j is at the far right of the array
  • In the case that the left and right pointers do not cross, the left pointer moves to the right, and the right pointer moves to the left
  • Add to the List collection if the conditions are met; if not, repeat the above steps after moving the fixed pointer

Code

class Solution {
    
    
    public List<List<Integer>> threeSum(int[] nums) {
    
    
   
       Arrays.sort(nums); //数组排序,方便去重
        List<List<Integer>> res = new ArrayList<>(); //结果集合

        for(int k = 0; k < nums.length - 2; k++){
    
     //k是第一个固定的指针
            if(nums[k] > 0)  //k位置的都大于0了,后面的肯定都大于0了
                break;
            if(k > 0 && nums[k] == nums[k - 1])  //去重
                continue;
            int i = k + 1; //双指针的左边的指针
            int j = nums.length - 1;  //双指针的右边的指针
            while(i < j){
    
     //满足左边指针在左边,右边指针在右边(不交叉)
                int sum = nums[k] + nums[i] + nums[j]; //求和
                if(sum < 0){
    
     //和小于0,左边指针向右移动
                    while(i < j && nums[i] == nums[++i]);
                } else if (sum > 0) {
    
    //和大于00,右边指针向左移动
                    while(i < j && nums[j] == nums[--j]);
                } else {
    
     //和等于0,满足条件,元素放入结果集合
                    res.add(new ArrayList<Integer>(Arrays.asList(nums[k], nums[i], nums[j])));
                    //想要找下一个0的话,必须左指针元素值增加,右指针元素值减小
                    while(i < j && nums[i] == nums[++i]);//左指针继续右移(在0的基础上增加)
                    while(i < j && nums[j] == nums[--j]); //右指针继续左移(在0的基础上减少)
                }
            }
        }
        return res; //返回结果集合
    }
}

insert image description here

Guess you like

Origin blog.csdn.net/weixin_44480968/article/details/124027493