leetcode Scratch Record - -- 19.9.13

Posted by fukumdaryl on Sat, 14 Sep 2019 04:08:08 +0200

Summary

1. The k th largest element in the array, using the idea of fast partition, plus binary retrieval

2. Bit count, the intuitive method of time complexity is o (n*sizeof(int). The effective way to reduce time complexity is to judge the parity of the current number, and then contact the previous one to draw a conclusion.

3. Longest ascending subsequence, dynamic programming o(n^2), greed + dichotomy o(nlogn).Maintain an array, if the new one is larger than the last one, put it in the back, otherwise find the first one larger than the new one and replace it.This lookup belongs to a lookup in an ordered array and can be found in half.

4. Rebuild the queue based on height, this topic first sorted by height and number (complex sort using sort, custom sort rules).Then interpolate to the appropriate location in the array based on the number of people.

5. Find the number of repetitions, o(logn) uses the dichotomy search to determine the number of left and right numbers.

6. Ring list, find the entrance to the ring of the chain list.Two methods, unordered_set and fast and slow pointers.Fast and slow pointers are mainly derived formulas that show why A = (n-1)(B+C)+C

 

 

 

1. The k th largest element in the array, passing through it all at once, is strange

Title Description: Given an unordered array, find the k th largest number in the array.

Idea: Fast Painting Function

Example 1:

Input: [3,2,1,5,6,4] and k = 2
Output: 5
Example 2:

Input: [3,2,3,1,2,4,5,5,6] and k = 4
Output: 4

class Solution {
public:
    void swap(int& a,int& b){int temp = a;a = b;b = temp;}
    int Partition(vector<int>& nums,int start,int end){
        int pivotKey = nums[start];
        while(start<end){
            while(pivotKey<=nums[end]&&start<end) end--;
            swap(nums[start],nums[end]);
            while(pivotKey>=nums[start]&&start<end) start++;
            swap(nums[start],nums[end]);
        }
        return start;
    }
    int findKthLargest(vector<int>& nums, int k) {
        int pp = nums.size()-k;
        int end = nums.size()-1;
        int pivot = Partition(nums,0,end);
        while(pp!=pivot){
            if(pp<pivot){pivot = Partition(nums,0,pivot-1);}
            else{pivot = Partition(nums,pivot+1,end);}
        }
        return nums[pp];
    }
};

2. Bit Count

Title Description: Given an integer, the number of 1 in the binary of all the numbers from 0 to this integer is put into the corresponding array.

Requirement, time o(n).....self-implemented o(nlogn).

Ideas with o(n) time complexity:

The number of 1 is determined by parity.(

1. If n is odd, then the number of his 1 equals the sum of the previous number plus one

2. If n is an even number, then the number of his 1 is equal to the number of his normal number of 1....(Critical!!!!!!)

    int countCore(int number){
        int count = 0;
        while(number){
            count++;
            number = (number-1)&number;
        }
        return count;
    }
    vector<int> countBits(int num) {
        vector<int> res(num+1,0);
        for(int i = 1;i<=num;++i){
            res[i] = countCore(i);
        }
        return res;
    }


//o(n) Solution
class Solution {
public:
    
    vector<int> countBits(int num) {
        vector<int> res(num+1,0);
        for(int i = 1;i<=num;++i){
            if(i&1 == 1) res[i] = res[i-1]+1;
            else{
                res[i] = res[i/2];
            }
        }
        return res;
    }
};

3. Longest ascendent sequence (more difficult)

Title Description: Given an unordered array, find its longest subsequence. Note that the subsequences can be discontinuous!Require time complexity o(nlogn)

Reference resources: https://leetcode-cn.com/problems/longest-increasing-subsequence/solution/dong-tai-gui-hua-er-fen-cha-zhao-tan-xin-suan-fa-p/

Ideas: dynamic programming o(n^2), binary search + greedy o(nlogn)

Dynamic Planning:

1. Define the status.

The dp[i] denotes the length of the "longest ascending subsequence" ending with the first digit.Within the range of [0,1,...,i], select the length of the longest ascending subsequence available ending with the number nums[i].Nums[i] must be selected.Initialize, all DPS can be initialized to 1.Define the input, the title is not state, so look through the DP array to find the largest.

2. Deduce the state transfer equation.

         dp[i] = max{1+dp[j] for j<i if nums[j]<nums[i]}

Binary Search + Greed:

1. Maintain an ascending array and store the rule that if an array element comes, it will be larger than the last element of the array.

2. During traversing an array, if it is larger than the last element of the array, then after loading the array, the length of the array is added by one

3. Otherwise you will find the place where this element is stored in this ascending array. If it already exists, it will not be updated. If it is in the middle of two numbers, replace the latter one.

This step uses binary search.(try to make the end of the auxiliary array smaller, which makes it more likely to construct a longer ascending subsequence)

4.tail length is the result

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int len = nums.size();
        if(len<2) return len;
        vector<int> temp;
        temp.push_back(nums[0]);
        int end = 0;
        for(int i = 1;i<len;++i){
            if(nums[i]>temp[end]){
                temp.push_back(nums[i]);
                end++;
            }
            else{
                int start = 0;
                int right = end;
                while(start<right){
                    int mid = (start+right)>>1;
                    if(temp[mid]<nums[i]) start = mid+1;
                    else right = mid;
                }
                temp[start] = nums[i];
            }
        }
        return end+1;
        
    }
};

4. Rebuild Queues Based on Height

Title Description: Given a set of data, it stores a pair of values [x,y], x denotes the person's height, y denotes that in front of this person there is another person whose height is greater than or equal to that person.Require sorting of these disordered data.

Reference resources: https://leetcode-cn.com/problems/queue-reconstruction-by-height/solution/406-gen-ju-shen-gao-zhong-jian-dui-lie-pai-xu-hou-/

Ideas:

1. Set up an auxiliary array to pick the highest person first and sort them in ascending order of times.Sort (people.begin(), people.end(), [] (vector <int>&a, vector <int>&b){...}) // Learn to sort as you like using sort here.

2. Select the highest person from the candidate array and insert the appropriate location for the auxiliary array.For (auto &e:people) {res.insert(res.begin()+e[1], e);}

class Solution {
public:
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        //Sort first, then insert one more
        sort(people.begin(),people.end(),[](const vector<int>&a,const vector<int>&b){
           if(a[0] > b[0]) return true;
            if(a[0] == b[0]&&a[1]<b[1]) return true;
            return false;
        });
        vector<vector<int>> res;
        for(auto &e:people){
            res.insert(res.begin()+e[1],e); 
        }
        return res;
    }
};

 

5. Finding the number of repetitions 287.....The key is the boundary condition

Title Description: Given an array of size n+1 with numbers from 1 to n, if only one number is repeated, find out who he is and he may repeat it many times.

Requires that the spatial complexity of o(1) be less than o(n^2), that the original array cannot be changed, and that number may recur n times.

Reference resources: https://leetcode-cn.com/problems/find-the-duplicate-number/solution/er-fen-fa-si-lu-ji-dai-ma-python-by-liweiwei1419/

Think: None, think of the duplicate digits with binary positioning on the offer of the sword finger

1. Count the number of numbers less than n/2 with n/2 as the limit

2. If the number of numbers is greater than n/2, on the left, end = mid+1; note the boundary condition[,

3. Conversely, on the right, start = mid; * Note the boundary conditions []

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        //Sort first, then double pointer.... No, you can't change the original array
        //Search with Dichotomy
        int len = nums.size();
        int start = 0;
        int end = len-1;
        while(start<end){
            int mid = (start+end)>>1;
            int count = 0;
            for(auto num:nums){
                if(num<=mid) count++; 
            }
            if(count>mid) end = mid;
            else start = mid+1;
        }
        
        return start;
    }
};

6. Ring Chain List II

Title Description: Given a list of chains, determine if there are rings and find the entrance to the rings.

Think: 1. Fast and slow pointers 2. Short unordered_set code

Fast or slow pointer:

1. At the first encounter, the slow pointer travels a distance of: slow=A+B.The path the fast pointer takes is: fast=A+n(B+C)+B.

2. Because the fast pointer must travel twice as far as the slow pointer, there are 2(A+B) = A+n(B+C)+B.Simplified to A = (n-1)(B+C)+C

3. Point the fast pointer at the head and change the forward step to 1.When you take step A with the improved fast pointer, it will definitely coincide with the slow pointer at the entrance.

unordered_set:

1. Define unordered_set.

2. As long as the head is not empty and there is no head in the set, add it to the set.

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        // unordered_set<ListNode*> myset;
        // while(head){
        //     if(myset.count(head)>0) return head;
        //     else myset.insert(head);
        //     head = head->next;
        // }
        // return nullptr;
        
         
        
        ListNode* pfast = head;
        ListNode* pslow = head;
        ListNode* ptemp = head;
        bool hasCycle = false;
        while(pfast != nullptr && pfast->next != nullptr){
            pslow = pslow->next;
            pfast = pfast->next->next;
            if(pslow == pfast){
                hasCycle = true;
                while(hasCycle && ptemp != pslow){
                    ptemp = ptemp->next;
                    pslow = pslow->next;
                }
                break;
            }
        }
        return hasCycle?pslow:nullptr;
    }
};

 

 

Topics: Programming less Python