Array series - traversal of arrays

Posted by algy on Tue, 30 Nov 2021 08:27:56 +0100

895. Maximum continuous 1

Given a binary array, calculate the maximum number of consecutive ones.

Example:

Input: [1,1,0,1,1,1]
Output: 3
Explanation: the first two digits and the last three digits are consecutive ones, so the maximum number of consecutive ones is 3

Source: LeetCode
Link: https://leetcode-cn.com/problems/max-consecutive-ones
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Idea:

1. Find the position of the first 1 a   [ i ]

2. a   [i] Yes = = a [i + 1] (if equal, count is returned; if not, start to find the position of the second 1 and return max at the same time.)

3. Repeat step 2

4. If the second max is larger than the first, the new Max is returned

class Solution {
    public int findMaxConsecutiveOnes(int[] nums) {
        int max = 0; int count = 0;
        for(int i=0;i<nums.length;i++){
            if(nums[i]==1) count++;
            else{
                if(count>max)max=count;
                count = 0;
            }
        }
        if(count>max)max=count;
        return max;
    }
}

About code optimization: else here is the case where num [i] = = 0, which will lead to a situation that if the last element is 1, a new max value will not be returned. Therefore, you need to add an if judgment statement outside the for loop.

For optimization, else can be removed on the basis of leetcode comments, so that the judgment statements outside the for loop can be removed.

The time complexity is O(n) and the space complexity is O(1)  

Through the research of leetcode comments, I found that there is also a method of writing with double pointers

class Solution {
    public int findMaxConsecutiveOnes(int[] nums) {
        if(nums.length == 0) return 0;
        int fast = 0,slow = 0;
        int num = 0;
        while(fast < nums.length){
            if(nums[fast]==0) {
                num = (fast - slow) > num ? fast - slow : num ;
                slow = fast + 1;
                fast++;
            }else{
                fast++;
            }
        }
        num = (fast - slow) > num ? fast - slow : num ;
        return num;
    }
}

The method is written here, which is also worth looking at. This idea came to mind at the moment of writing the topic, that is, find the position of 0 in the array, and then subtract the position of the previous 0 from the position of 0 for comparison.

495. Timo attack

In the world of the League of heroes, there is a hero named Timo. His attack can poison the enemy hero Aishi.

When Timo attacks ash, ash's poisoning continues   duration seconds.

Formally speaking, Timo's attack at t means that ash is poisoned in the time interval [t, t + duration - 1] (including T and T + duration - 1). If Timo attacks again before the end of the poisoning effect, the poisoning status timer will be reset. After a new attack, the poisoning effect will end in duration seconds.

Give you a non decreasing integer array timeSeries, where timeSeries[i] means Timo launches an attack on Ash in timeSeries[i] seconds, and an integer duration representing the duration of poisoning.

Returns the total number of seconds that ash was poisoned.

 
Example 1:

Input: timeSeries = [1,4], duration = 2
Output: 4
Explanation: the impact of Timo attack on Aishi is as follows:
-In the first second, Timo attacks AI Xi and poisons him immediately. The poisoning state will last for 2 seconds, i.e. the first and second seconds.
-In the 4th second, Timo attacks AI Xi again, and AI Xi's poisoning state lasts for another 2 seconds, that is, the 4th and 5th seconds.
Ash is poisoned in the first, second, fourth and fifth seconds, so the total poisoning seconds is 4.
Example 2:

Input: timeSeries = [1,2], duration = 2
Output: 3
Explanation: the impact of Timo attack on Aishi is as follows:
-In the first second, Timo attacks AI Xi and poisons him immediately. The poisoning state will last for 2 seconds, i.e. the first and second seconds.
-In the second second, Timo attacks AI Xi again and resets the poisoning timer. AI Xi's poisoning state needs to last for 2 seconds, that is, the second and third seconds.
Ash is poisoned in the first, second and third seconds, so the total poisoning seconds is 3.

Source: LeetCode
Link: https://leetcode-cn.com/problems/teemo-attacking
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

  Idea:

Returns the total number of seconds poisoned

1. Set two variables: the total time and the number to be added in each round

2. Perform a for loop traversal of the array timeSeries

3. If the difference between the two element values is greater than duration, duration is returned as the added quantity

4. If the difference of element values is smaller than duration, the element difference is returned as the number of additions

5. The value of the last return needs to be added with a duration (because the last element is not taken into account)

class Solution {
    public int findPoisonedDuration(int[] timeSeries, int duration) {
        int timeSum = 0;
        int timeAdd = duration;
        for(int a=0;a<timeSeries.length-1;a++){
           if(timeSeries[a]+duration>timeSeries[a+1]) {
                timeAdd=timeSeries[a+1]-timeSeries[a]; 
                timeSum=timeSum+timeAdd;
                }
           else {timeAdd=duration;timeSum=timeSum+timeAdd;
            }
        }
        return timeSum+duration;
    }
}

leetcode method 1

Each time the element difference is compared with the duration size, the small value is returned as the added value. (extremely clever)

class Solution {
    public int findPoisonedDuration(int[] timeSeries, int duration) {
        if (timeSeries.length == 1) {
            return duration;
        }
        int ans = 0;
        for (int i = 0; i < timeSeries.length - 1; i++) {
            ans += Math.min(timeSeries[i + 1] - timeSeries[i], duration);
        }
        return ans + duration;
    }
}

leetcode method 2

First assume that the poisoning time is full, and then subtract the repeated time.

  public int findPoisonedDuration(int[] timeSeries, int duration) {
        int res = timeSeries.length * duration;
        for(int i = 1; i < timeSeries.length; i++){
            if(timeSeries[i] - timeSeries[i-1] < duration){
                res -=  duration - timeSeries[i] + timeSeries[i-1];
            }
        }
        return res;
    }

414.

Give you a non empty array and return the third largest number in the array. If it does not exist, the maximum number in the array is returned.

Example 1:

Input: [3, 2, 1]
Output: 1
Explanation: the third largest number is 1.
Example 2:

Input: [1, 2]
Output: 2
Explanation: the third largest number does not exist, so the maximum number 2 is returned.
Example 3:

Input: [2, 2, 3, 1]
Output: 1
Explanation: note that the third largest number is required to be returned, which means the third largest number among all different numbers.
In this example, there are two numbers with a value of 2, both of which are second. The third largest of all the different numbers is 1.

Source: LeetCode
Link: https://leetcode-cn.com/problems/third-maximum-number
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Idea:

1. First sort the array from small to large (ideally, it should be from large to small)

2. The for loop traverses the array

3. Compare the size of num [i] and num [I-1]

4. Return num [I-1] when the equal condition is reached twice

class Solution {
    public int thirdMax(int[] nums) {
        Arrays.sort(nums);
             for(int i =nums.length-1,j =1;i>0;i--){
                 if(nums[i]!=nums[i-1]){
                     j++;
                     if(j==3) return nums[i-1];
            }
        }
        return nums[nums.length-1];
    }
    }

628.

Give you an integer array nums, find the maximum product of three numbers in the array, and output the product.

Example 1:

Input: num = [1,2,3]
Output: 6
Example 2:

Input: num = [1,2,3,4]
Output: 24
Example 3:

Input: num = [- 1, - 2, - 3]
Output: - 6

Source: LeetCode
Link: https://leetcode-cn.com/problems/maximum-product-of-three-numbers
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

  Idea:

1. Sort the array first because you want to find the maximum product of three numbers

2. If the largest number after array sorting is less than or equal to 0, the maximum value is equal to the multiplication of the last three numbers

3. If the largest number after array sorting is greater than 0, there are two cases:

(1) Maximum = the last number multiplied by the two smallest negative numbers

(2) Maximum = multiply the last three numbers (all positive numbers)

4. Complete the algorithm

class Solution {
    public int maximumProduct(int[] nums) {
        int length = nums.length-1;
         Arrays.sort(nums);
         if(nums[length]>0)
         { 
             int max =nums[length]*nums[length-1]*nums[length-2];
            int min =nums[0]*nums[1]*nums[length];
        return Math.max(max,min);
         }
        else{
            return nums[length]*nums[length-1]*nums[length-2];
        }
        
    }
}

Optimize:

The judgment of if else can be removed, because no matter how compared, it is actually two cases 1 --- the last two negative numbers multiplied by the largest number   2 --- multiply the three largest numbers    

Direct mathematical judgment

class Solution {
    public int maximumProduct(int[] nums) {
        int length = nums.length-1;
         Arrays.sort(nums);
             int max =nums[length]*nums[length-1]*nums[length-2];
            int min =nums[0]*nums[1]*nums[length];
        return Math.max(max,min);
        
    }
}

Time complexity O(nlogn)  , Spatial complexity O(logn)

Method seen in leetcode comments: one-time traversal

class Solution {
    public int maximumProduct(int[] nums) {
        // The smallest and second smallest
        int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
        // The largest, second and third largest
        int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE;

        for (int x : nums) {
            if (x < min1) {
                min2 = min1;
                min1 = x;
            } 
            else if (x < min2) {
                min2 = x;
            }
            if (x > max1) {
                max3 = max2;
                max2 = max1;
                max1 = x;
            } else if (x > max2) {
                max3 = max2;
                max2 = x;
            } else if (x > max3) {
                max3 = x;
            }
        }

        return Math.max(min1 * min2 * max1, max1 * max2 * max3);
    }
}

New knowledge to know: if... else if. Each else should be paired with a corresponding if. An if... else if is a combination.

 if (x < min1) {
                min2 = min1;
                min1 = x;
            } 
            else if (x < min2) {
                min2 = x;
            }

If   If x < Min1 is not true, execute else if(). If it is true, do not execute.

It is equal to the following code

  if(x<min2){

                if(x<min1){

                    min2 = min1;

                    min1 = x;

                }

                else min2 = x;

            }

  In fact, it is a combination of if else if, and so is the second if combination.

So far, I have finished the traversal of the first array in the question brushing series

The corresponding leetcode topics are 485, 495, 414, 628

Topics: Java Back-end