Algorithm training phase I

Keywords: C++ network Programming Java less

Overview of the first phase of algorithm

As the first phase of algorithm training, it is not difficult. But as a normal algorithm learner. We should not be bound by the present, so we will talk about as many ways as possible. As a review of previous algorithm learning. The methods used here will be described in detail in other documents.

Missing numbers from 0 to n-1

Title Description: all numbers in an increasing sort array with length of n-1 are unique, and each number is in the range of 0-n-1. Among the N numbers in the range 0-n-1, only one number is not in the array. Please find this number.

Example 1:

Input: [0,1,3]

Output: 2

Example 2:

Input: [0,1,2,3,4,5,6,7,9]

Output: 8

Limitations:

1 < = array length < = 10000

Ideas:

One by one, until nums [i]! = I.

There are different ways to find one by one:

  1. Only if is used to distinguish;
  2. Press "exclusive or" operation;
  3. Calculate the sum of all the numbers in the nums array, and then subtract one by one. After the last reduction, just return directly;

The code will be given later.

But the idea here is a dichotomy;

We don't want to find one by one, but we use the natural condition of order. Use dichotomy.

Code (code from network):

//Bitwise exclusive or operation
class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int res=nums.size();
        for(int i=0;i<nums.size();i++)
        {
            res^=nums[i];
            res^=i;
        }
        return res;
    }
};
//Subtract one by one with sum
class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int sum=(nums.size()*(nums.size()+1))/2;
        for(int i=0;i<nums.size();i++)
        {
            sum-=nums[i];
        }
        return sum;
    }
};
//dichotomy
int GetMissingNum(const int* num, int len)
{
    if(num == NULL || len <= 0)
        return -1;
 
    int left = 0; //Binary search leftmost element subscript
    int right = len-1;    //Binary search right most element subscript
 
    while (left <= right)    //Search process
    {
        int mid = (left + right) >> 1;    //Middle element subscript
 
        if(num[mid] != mid)    //Indicates that there is an element missing at or to the left of the mid
        {
            //If mid == 0 or the number and subscript of the previous element of mid are equal, mid is the required
            if(mid == 0 || num[mid-1] == mid - 1)
                return mid;
 
            right = mid - 1;    //right decrease, left decrease range, continue searching
        }
        else //Search right half
        {
            left = mid + 1; 
        }
    }
 
    if (left == len)    //Find the last element, which is the
        return len;
 
    return -1;    //Invalid input, return - 1
}

Longest continuous increasing sequence

Description: given an unsorted array of integers, find the longest and continuous increasing sequence, and return the length of the sequence.

Example 1:

Input: [1,3,5,4,7]
Output: 3
Explanation: the longest continuous increasing sequence is [1,3,5], and the length is 3. Although [1,3,5,7] is also a subsequence of ascending order, it is not continuous because 5 and 7 are separated by 4 in the original array.

Example 2:

Input: [2,2,2,2,2]
Output: 1
 Explanation: the longest continuous increasing sequence is [2], and the length is 1.

Limit: array length cannot exceed 10000.

Ideas:

Here are two ideas:

  1. Sliding window: a sliding window that looks for each element one by one.
  2. Dynamic planning: after that, special documents explain all kinds of dynamic planning. The dynamic programming of this topic is relatively easy. It does not need to display the dp array but only needs to give the result.

code:

//Double pointer
class Solution {
public:  // sliding window
    int findLengthOfLCIS(vector<int>& nums) {
       if(nums.empty()) return 0;
       int n=nums.size(),ans=0,ancher=0;
       for(int i=0;i<n;i++){
           if(nums[i-1]>=nums[i]){
               ancher=i; // Change the sliding window once
           }else{
                ans=max(res,i-ancher+1);  // Update res when changing sliding window
           } 
       }
    return ans;
    }
};
//Dynamic planning:
class Solution {
public:
    int findLengthOfLCIS(vector<int>& nums) {
        if(nums.empty()) return 0;
        int n = nums.size(), cnt = 1, ans = 1;
        if(n<=1) return n;
        for(int i=1;i<n;i++)
        {
            if(nums[i]>nums[i-1])
                cnt++;
            else cnt = 1;
            ans = max(ans, cnt);
        }
        return ans;
    }
};
//Double pointer:

class Solution {
public:
    int findLengthOfLCIS(vector<int>& nums) {
        if(nums.empty()) return 0;
        int n=nums.size(),first=0,second,ans=1;
        for(second=1;second<n;)  // The next pointer goes through to the end
        {
            int tem=1;            
            if(nums[second]>nums[second-1])  // Fix the first pointer to get an ordered number
            {                
                second++;
                tem=second-first;  // Fix the first pointer to get the maximum number
                ans=max(ans,tem);
            }
            else   // When it is not greater than the previous one,
            {
                first=second;  // Point the slow pointer to the current value
                second++;  // Move the pointer forward
                ans=max(ans,tem);  //Compare the current maximum value with the previous answer
                tem=1;
            }            
        }
    return ans;
    }
};

Merge two ordered arrays

Description:

Here are two ordered integer arrays nums1 and nums2. Please merge nums2 into nums1 to make nums1 an ordered array.

explain:

  • The number of elements to initialize nums1 and nums2 is m and n, respectively.
  • You can assume that nums1 has enough space (space size greater than or equal to m + n) to hold the elements in nums2.

Example:

Input:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3

Output: [1,2,2,3,5,6]

Ideas:

code:

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int i = m - 1; //As a pointer to the nums1 array
        int j = n - 1; //As a pointer to the nums2 array
        int p = m + n - 1;  //Position pointer to the final nums1 array
        while(j >= 0 && i >= 0){
            if(nums2[j] > nums1[i]){
                nums1[p--] = nums2[j--];
            }
            else{
                nums1[p--] = nums1[i--];
            }
        }
        while(i >= 0){
            nums1[p--] = nums1[i--];
        }
        while(j >= 0){
            nums1[p--] = nums2[j--];
        }
    }
};

Distance between bus stops

Description:

There are n stops on the ring bus route, numbered in order from 0 to n - 1. We know the distance between each pair of adjacent bus stops. distance[i] refers to the distance between the station with number I and the station with number (I + 1)% n.

The buses on the loop line can be driven clockwise and anticlockwise.

Return the shortest distance between the passenger's start ing point and the destination.

Example 1:

Input: distance = [1,2,3,4], start = 0, destination = 1
Output: 1
Explanation: the distance between bus stops 0 and 1 is 1 or 9, and the minimum value is 1.

Example 2:

Input: distance = [1,2,3,4], start = 0, destination = 2
Output: 3
Explanation: the distance between bus stops 0 and 2 is 3 or 7, and the minimum value is 3.

Example 3:

~~~~

Input: distance = [1,2,3,4], start = 0, destination = 3
Output: 4
Explanation: the distance between bus stops 0 and 3 is 6 or 4, with a minimum of 4.

Limitations:

  • 1 <= n <= 10^4
  • distance.length == n
  • 0 <= start, destination < n
  • 0 <= distance[i] <= 10^4

Ideas:

It is similar to the idea of complement: sum is certain, and there is only one ring, so the situation is whether the direct distance D or the reverse distance sum-d is smaller.

code:

class Solution {
public:
    int distanceBetweenBusStops(vector<int>& distance, int start, int destination) {
        int sum = 0;
        int a = 0,i;
        for(int i = 0; i < distance.size(); i++)
        {
            sum+=distance[i];
        }
        
        for(i = start>destination?destination:start ; i < (start>destination?start:destination); i++)
        {
            a += distance[i];
        }
        return a>(sum-a)?(sum-a):a;
    }
};

Delete duplicates in array

Description:

Given a sort array, you need to delete duplicate elements in place so that each element appears only once, returning the new length of the array after removal.

Do not use extra array space, you must modify the input array in place and do so with O(1) extra space.

Example 1:

Given array nums = [1,1,2],

The function should return a new length of 2, and the first two elements of the original array nums are modified to 1, 2.

You don't need to think about the elements in the array that follow the new length.

Example 2:

Given nums = [0,0,1,1,1,2,2,3,3,4],

The function should return a new length of 5, and the first five elements of the original array nums are modified to 0, 1, 2, 3, 4.

You don't need to think about the elements in the array that follow the new length.

explain:

Why is the return value an integer, but the output answer is an array?

Note that the input array is passed by reference, which means that modifying the input array in a function is visible to the caller.

You can imagine the internal operation as follows:

//nums is passed by reference. That is, do not make any copies of the arguments
int len = removeDuplicates(nums);

//Modifying the input array in a function is visible to the caller.
//Depending on the length returned by your function, it prints out all elements in the array within that length range.
for (int i = 0; i < len; i++) {

print(nums[i]);

}

Ideas:

First of all, the modification is visible to the array caller. This means don't take out the element and throw it into the set directly, and then return the result. Write it by yourself.

Train of thought 1:

The core idea of the problem is scanning and replacing. You can still use the double pointer operation.

Train of thought 2:

Use index to record the number of non repeating numbers.

If nums [i]! = nums [I-1], a new non repetitive value will appear. Make nums[index] = nums[i] OK

It is worth noting that the first number nums[0] must be recorded. So the condition is that i-1 is not i+1, and i+1 needs to judge the array.

Idea 3:

In thinking 2, when it is not equal, it is judged that there are not repeated numbers. But the number is increasing, so only the latter > the former one also appears new non repeating numbers. Its advantage is to solve the special case of train of thought 2, that is, empty array.

code:

//Double pointer (Java can also implement pointer idea):
public class Solution {
    
    public int replaceTwo(int[] nums){
        

             if(nums.length <= 2) {
                return nums.length;
            }
             //1,1,1,2,2,3
             
            int count = 1;
            //count is the number of element repetitions
            int k = 1;
     //The core idea is to replace, omit the part with element repetition more than 2, and move other legal elements to the previous legal area.      
     //Here, i and k are used to scan at the same time. However, when the count of the elements is not less than 2, (that is, when the number of equal times of the two elements reaches 2, that is, when the number of the same elements reaches 3)
     //At this time, K will stop until i find the next coordinate that is not equal to the current k-1, then continue to replace and repeat all operations.       
            for(int i = 1; i < nums.length; i++){
                //If equal, repeat times plus 1
                if(nums[i] == nums[i-1]) {
                    
                    if(count < 2) {
                        //When the repetition reaches two times, the transformation operation is carried out
                        nums[k++] = nums[i];
                        count++;
                    }
                }else {
                    //I don't want to wait if I meet two numbers. Then count times
                    count = 1;
                    nums[k++] = nums[i];
                    
                }
            }
            
            return k;
        
    }
    
    public static void main(String[] args) {
        Solution sl = new Solution();
        int nums1[] = {0,0,1,1,1,2,3,3};
        int nums2[] = {0,0,1,1,1,2,3,3};
        int len1 = sl.replaceTwo(nums1);
        int len2 = sl.replaceTwo(nums2);
        for(int i = 0;i < len1; i++){
            System.out.print(nums1[i] + " ");
        }
        System.out.println();
        for(int j = 0;j < len2; j++){
            System.out.print(nums2[j] + " ");
        }
    }
}

//Train of thought 2
class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int n = nums.size();
        if (n == 0) {
            return 0;
        }
        int index = 0;
        // nums[0] does not change. index is assigned from 1.
        for (auto i = 1; i < n; ++ i) {
            if (nums[i] != nums[i - 1]) {
                index ++;
                nums[index] = nums[i];
            }
        }
        return index + 1;
    }
};
//Train of thought 3
class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int i = !nums.empty();
        for (int n : nums)
            if (n > nums[i - 1])
                nums[i ++] = n;
        return i;
    }
};

Posted by PeterPopper on Sat, 20 Jun 2020 21:24:09 -0700