The interviewer asked me to go back and look at the first question.

Posted by greatepier on Thu, 30 Dec 2021 23:03:46 +0100

⭐ Introduction ⭐ Neodymium
Hi everyone, I'm stuck. Today we are explaining the series of classical sums. It's good to say that some people can't do the first thing while watching the sea at night. You should all know that the first question of power button is the sum of two numbers. But in fact, the sum of two numbers is only the beginning. In the advanced stage, there are also the sum of three numbers, the sum of four numbers and the addition of four numbers. Today, I will integrate this series for you from easy to difficult, in which various methods are analyzed in detail, to help you summarize the laws, so as to achieve the effect of "one against three". Suggest everyone to collect for easy training.

At the same time, I recommend my list topic for brothers, to help you tear the list by hand, and to train systematically- Chain List Theme

📒 Blog Home Page: Obligated Blog

🎉 Welcome to your attention 🔎 Give the thumbs-up 👍 Collection ⭐ Message 📝

❤️ : Love Java and algorithm learning, look forward to communicating!

🙏 Author level is limited. If you find any errors, please let me know. Thank you!

🌺 Have questions to communicate privately!!! * On

⭐ Navigation Assistant ⭐ Neodymium

🍋 1. Title brushing and viewing instructions

🍋 2. Training step by step and buckle up the battle effectiveness

* 🐱 1. Sum of Two Numbers

* 🐭 2.Sum of Two Numbers|| - Enter Ordered Array

* 🐸 3. Sum of Two Numbers IV - Input BST

* 🐶 4. Sum of Three Numbers

* 🐯 5. Sum of Four

* 🐷 6.Four digits plus ll

🍋 3. Summary of brushing

🍋 1. Title brushing and viewing instructions

Several geometry series is one of the most classical series of problems, and each of them has a wide variety of solutions. Various knowledge of algorithms are used, such as violent enumeration, hashing, sorting + double pointer, and so on. However, although many people can do it, it will only be a simple solution, which is complacent. This kind of questions must be able to do all kinds of bypass. I hope you can solve each problem in a variety of ways, and at the same time summarize the rules of this kind of questions.

🍋 2. Training step by step and buckle up the battle effectiveness

* 🐱 1. Sum of Two Numbers

Given an array of integers nums and an integer scalar target, find the two integers in the array that are the target and return their array subscripts.

You can assume that each input corresponds to only one answer. However, the same element in the array cannot be repeated in the answer.

You can return the answers in any order.

Title link: Sum of Two Numbers

As the first topic of power deduction, it is the starting point for many people to become absolute. This topic also has its own beauty.

Title Analysis: The first thought must be violent traversal, followed by the use of hash tables. There are also different ways to solve hash tables. Here we use Hashmap, which stores values with key and subscripts with value. We traverse the array nums[i] to find out if there are any matching numbers in the hash table. Otherwise, we return two subscripts, or we put nums[i] in the hash table.

1. Traversal of Violence

Time Complexity O(N^2): With a two-tiered for loop, at worst every two numbers will be traversed several times

Spatial Complexity O(1): Array Space of Constant Order

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

2. Using HashMap

Time Complexity O(N): A group is traversed only once

Spatial Complexity O(N): Mainly the overhead of the hash table

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int n=nums.length;
        //key holds value, value holds subscript
        Map<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<n;i++){
            //Eureka
            if(map.containsKey(target-nums[i])){
                //Return Subscript
                return new int[]{map.get(target-nums[i]),i};
            }
            //No place in map found
            map.put(nums[i],i);
        }
        //End of traversal still not found
        return new int[0];
    }
}

* 🐭 2.Sum of Two Numbers|| - Enter Ordered Array

Given an array of integers in a non-decreasing order, find out from the array that the sum of two numbers satisfies the sum equal to the target number.

The function should return the subscript values of these two numbers as an array of integers of length 2. Numbers'subscripts count from 1, so the answer array should satisfy 1 <= answer[0] < answer[1] <= numbers. Length.

You can assume that each input corresponds to a unique answer, and that you cannot reuse the same elements.

Title link: Sum of Two Numbers|| - Enter Ordered Array

Idea Analysis: This problem can be solved using violence and hash tables as before, but that's for unordered arrays. Because it's an ordered array, we naturally want to have a double pointer, traversing from both ends. When the element added by two pointers is greater than the target, the right pointer moves to the left, and when less than the target, the left pointer moves to the right.

Time Complexity: O(n), where n is the length of the array and the two pointers move up to N times in total

Spatial Complexity: O(1)

class Solution {
    public int[] twoSum(int[] numbers, int target) {
         int n=numbers.length;
         int left=0;
         int right=n-1;
         while(left<right){
             int count=numbers[left]+numbers[right];
             //Find it, but add 1 to the subscript because the title requires it
             if(count==target){
                 return new int[]{left+1,right+1};
             //That adds up too much, right--, so the count gets smaller
             }else if(count>target){
                 right--;
             //Too small to add up, left++, so count gets bigger
             }else{
                 left++;
             }
         }
         return new int[0];
    }
}

* 🐸 3. Sum of Two Numbers IV - Input BST

Given a binary search tree root and a target result k, returns true if there are two elements in the tree and their sum is equal to the given target result. *

Title link: Sum of Two Numbers IV - Enter BST        

Title Analysis: This question is similar to the sum of the previous two numbers, except that the form of element storage becomes a tree, and we can also use Hashset to traverse the tree.

Method: Hashset adds traversing trees. Determine if k-root exists in the set when the current root is present. Val, returns true directly if it exists. If it does not exist, it will be the root at this time. Val is stored in the set, and the search continues in both the left and right subtrees.

Time complexity O(n), n is the number of nodes, and in the worst case, the whole tree is traversed once

Spatial Complexity O(n), in the worst case, set stores the values of n nodes.

class Solution {
    public boolean findTarget(TreeNode root, int k) {
        Set<Integer> set=new HashSet<>();
        return find(root,k,set);
    }
    public boolean find(TreeNode root,int k,Set set){
        //Return false directly if root is empty
        if(root==null) return false;
        if(set.contains(k-root.val)){
            return true;
        }
        //This one was added to the set collection if it was not found
        set.add(root.val);
        //Find both left and right subtrees
        return find(root.left,k,set)||find(root.right,k,set);
    }
}

* 🐶 4. Sum of Three Numbers

Give you a n array of n integers, nums, to determine if there are three elements a, b, c in nums so that a + b + c = 0? Please find all triples with sum 0 and no repetition.

Note: The answer cannot contain duplicate tuples.

Title link: Sum of Three Numbers        

Title Analysis: This question looks similar to the sum of two numbers, but it does not work the same way, it is not difficult at the same level, and the last few examples of simple violence will time out

Method 1: Simple violence (timeout)

* Time Complexity O(N^3)

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        int n=nums.length;
        List<List<Integer>> list=new ArrayList<>();
        for(int i=0;i<n-2;i++){
            for(int j=n-1;j>i+1;j--){
                int x=i+1;
                while(x<j){
                int count=nums[i]+nums[x]+nums[j];
                if(count==0){
                    List<Integer> arr=new ArrayList<>();
                    arr.add(nums[i]);
                    arr.add(nums[x]);
                    arr.add(nums[j]);
                    if(!list.contains(arr)){
                        list.add(arr);
                    }
                    x++;
                }else if(count>0){
                    break;
                }else{
                    x++;
                }
            }
            }
        }
        return list;
    }
}

Method 2: Sort plus Double Pointer

The idea: To facilitate weight reduction and reduce traversal times, we should ensure that the three pointers satisfy the relationship of i<j<k. IWe fix it by a for loop, and j and K move inward from both ends.

Time Complexity O(n^2): Array Sort O(nlogn), Traverse Array O(n), Double Pointer Traverse O(n). Overall O(n^2)

Spatial Complexity O(1)

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        //Sort Arrays
        Arrays.sort(nums);
        int n=nums.length;
        List<List<Integer>> list=new ArrayList<>();
        for(int i=0;i<n-2;i++){
            //Set an i, move the two pointers j,k, notice that J moves from the end
           int j=i+1;
           int k=n-1;
           while(j<k){
               int count=nums[i]+nums[j]+nums[k];
               //matches found
               if(count==0){
                   List<Integer> arr=new ArrayList<>();
                   arr.add(nums[i]);
                   arr.add(nums[j]);
                   arr.add(nums[k]);
                   //For weight removal
                   if(!list.contains(arr)){
                       list.add(arr);
                   }
                   j++;
                   k--;
                //Too much together to make k--and thus smaller
               }else if(count>0){
                   k--;
                //Too small to make j++ grow
               }else{
                   j++;
                   }
              }
        }
        return list;
    }
}

Optimize the above code:

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);//Sort, nums becomes an incremental array
        List<List<Integer>> res = new ArrayList<>();
        //K < nums. Length - 2 is to ensure there are two more numbers to follow
        for(int k = 0; k < nums.length - 2; k++){
            if(nums[k] > 0) break;//If nums[k] is greater than 0, the following number is also greater than zero (increasing after sorting)
            if(k > 0 && nums[k] == nums[k - 1]) continue;//nums[k] value repeated, weight removed
            int i = k + 1, j = nums.length - 1;//Define left and right pointers
            while(i < j){
                int sum = nums[k] + nums[i] + nums[j];
                if(sum < 0){
                    while(i < j && nums[i] == nums[++i]);//Left Pointer Forward and Remove Weight
                } else if (sum > 0) {
                    while(i < j && nums[j] == nums[--j]);//Right Pointer Back and Remove Weight
                } else {
                    res.add(new ArrayList<Integer>(Arrays.asList(nums[k], nums[i], nums[j]);
                    while(i < j && nums[i] == nums[++i]);//Left Pointer Forward and Remove Weight
                    while(i < j && nums[j] == nums[--j]);//Right Pointer Back and Remove Weight
                }
            }
        }
        return res;
    }
}

* 🐯 5. Sum of Four

Give you an array of n integers, nums, and a target value. Please find and return the four tuples [nums[a], nums[b], nums[c], nums[d], which satisfy all of the following conditions and do not repeat (two quaternions are considered duplicates if they correspond to one another):

0 <= a, b, c, d < n
a, b, c and d are different from each other
nums[a] + nums[b] + nums[c] + nums[d] == target
You can return the answers in any order.

Title link: Sum of Four        

Think about the topic: This topic is the first step on the basis of the sum of three numbers or the sum of two numbers, but it has only become four numbers. It's impossible to traverse with four for loops, and we have to weigh it. It's bound to time out. In this case, we can also use the property of the sum of three numbers, first sort the array, using four pointers i,p1,p2,j. I<p1<p2<j is also guaranteed. Each time I and j are fixed, determine the sum of the four subscripts added together, if larger than the target, let p2--, if smaller than the target, let p1+. If equal, place in the answer set.

Method: Sort plus Double Pointer

Time Complexity: O(n^3)

Spatial Complexity: O(logn)

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> list=new ArrayList<>();
        Arrays.sort(nums);
        int n=nums.length;
        //i Make sure there are three more digits left, so <n-3
        for(int i=0;i<n-3;i++){
            //There are two more bits between guaranteed and i, so > i+2
            for(int j=n-1;j>i+2;j--){
                int x=nums[i]+nums[j];
                //Position where the two pointers begin
                int p1=i+1;
                int p2=j-1;
                while(p1<p2){
                    int count=x+nums[p1]+nums[p2];
                    if(count==target){
                        List<Integer> arr=new ArrayList<>();
                        arr.add(nums[i]);
                        arr.add(nums[j]);
                        arr.add(nums[p1]);
                        arr.add(nums[p2]);
                        //Duplicate removal
                        if(!list.contains(arr)){
                          list.add(arr);  
                        }                       
                        p1++;
                        p2--;
                    }else if(count>target){
                        p2--;
                    }else{
                        p1++;
                    }
                }
            }
        }
        return list;
    }
}

* 🐷 6.Four digits plus ll

Give you four integer arrays nums1, nums2, nums3, and nums4. The length of the array is n. Please calculate how many tuples (i, j, k, l) you can have:

0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

Title link: Four-digit additive ll        

Title idea: This is actually simpler than the sum of the four numbers of the previous one, but it has its own more difficult points to deal with. It is impossible to traverse with four for loops, because the step of weight removal can be cumbersome even if the traversal does not time out. In fact, it is also equivalent to an advanced level of the sum of two numbers. We can add two or two groups of arrays, group A and group B traversals, and use the result as key and value as the number of times the result occurs. Then iterate through the sum of group C and group D as count to determine if there is a key in the map that adds zero to count and, if so, the value corresponding to that key. This is equivalent to two O(n^2) traversals and overall O(n^2) world complexity

Method: Grouping + Hash Table

Time Complexity O(n^2): Two two two-level for loops, overall time complexity or O(n^2)

Spatial Complexity O(n^2): The space required for hash mapping, and in the worst case, the number of digits n^2 that are stored, also the space required for O(n^2).

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        Map<Integer,Integer> map=new HashMap<>();
        int n=nums1.length;
        //Used to count answers
        int anser=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                int count=nums1[i]+nums2[j];
                //Already exists
                if(map.containsKey(count)){
                    //Add 1 to the number of occurrences, which is value
                   map.put(count,map.get(count)+1); 
                }else{
                    //No, put in map, value is 1
                    map.put(count,1);
                }
            }
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                int count2=nums3[i]+nums4[j];
                //Find a match
                if(map.containsKey(-count2)){
                    //Add value, that is, the number of occurrences
                    anser+=map.get(-count2);
                }
            }
        }
        return anser;
    }
}

🍋 3. Summary of brushing

The subject of Sum of Numbers is very dry, which gives an in-depth look at the practical application of our algorithm's basic capabilities. Especially for the training of hashing ability, because hashing is a classic space for time, it will time out if we don't use hashing, and heavy lifting can be very troublesome. Second is the use of double pointers, because most of the subject data for the sum of several numbers is in the array, and most of the elements in the array cannot be found without the double pointer algorithm. After you finish this type of topic, you must sum up more of its rules, from two to three to four, how it changes, and how does it change so that you can brush the topic efficiently and become refreshed as soon as possible! I will also follow up with the Hash and Dual Pointer thematic series. (

If it's useful, I hope your brothers can support you more than once!!! Thank

Final surprise:

      

 Java Learning Route Summary, Brick Movers Reverse Java Architect

Topics: Java Algorithm leetcode Double Pointer