LeetCode 300. Longest Increasing Subsequence rise longest sequence (C ++ / Java)

topic:

Given an unsorted array of integers, find the length of longest increasing subsequence.

Example:

Input: [10,9,2,5,3,7,101,18]
Output: 4 
Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4. 

Note:

  • There may be more than one LIS combination, it is only necessary for you to return the length.
  • Your algorithm should run in O(n2) complexity.

Follow up: Could you improve it to O(n log n) time complexity?

analysis:

A disorder of a given integer array, the length of the longest found rising sequence.

Note that this problem does not require rising sequence is continuous, we can go to observe such a problem, a known sequence [16,17,2,3,4] its biggest rise sequence is [2,3,4] If this when a 20 came, so we look.

If the ends 4 and 20 of the combination, it is our sequence at this time is [16,17,2,3,4,20] The maximum increase in sequence is [2,3,4,20], i.e. the maximum length 3 + 1 = 4 (sequence of the original sequence at a maximum lifting end length is 4 + 1).

If the ends 3 and 20 in combination, the sequence at this time we are [16,17,2,3,20] sequence is the maximum rise [2,3,20], the maximum length is 2 + 1.

If a combination of 2 and 20 ends, the sequence at this time we are [16,17,2,20] sequence is the maximum rise [2,20], the maximum length is 1 + 1.

You might ask at this time the biggest rise sequences should not be [16, 17] it? Remember, at this time we are seeking the maximum rise of 2 sub-sequence at the end, we can only be [2,20].

If the ends 17 and 20 in combination, the sequence at this time we are [16, 17] sequence is the maximum rise [16, 17], the maximum length is 2 + 1.

If the ends 16 and 20 in combination, the sequence at this time we are [16, 20] sequence is the maximum rise [16, 20], the maximum length is 1 + 1.

We can re-iterate, each new element, and then go to all the previous elements as compared to if the new element is larger than the current element, it means that the new element to the current element can and ending with the largest increase in child the new sequence of the maximum increase in sequence, and the new maximum length equal to the length increase subsequence +1 maximum rise subsequence ending at the current element, so that some may sound convoluted. We created a new array, and as large as the size of the original array, the corresponding location stores the length of the maximum rise subsequence of this element is ending.

10              
1              
10 9            
1 1            
10 9 2          
1 1 1          
10 9 2 5        
1 1 1 2        
10 9 2 5 3      
1 1 1 2 3      
10 9 2 5 3 7    
1 1 1 2 2 3    
10 9 2 5 3 7 101  
1 1 1 2 2 3 4  
10 9 2 5 3 7 101 18
1 1 1 2 2 3 4 4

Each new element, and should be in front of each element to the end of the sequence to compare can become a new rising sequences. And finally returns the largest value in the array, i.e., the maximum increase in the length sequence, so that the time complexity is O (n ^ 2).

Now we look at it again O (nlogn) method, we use a binary search dp array to maintain one of the most promising rising sequence.

We know that if a sequence [10,20,30,1,2,3 .....], it is clear that 1,2,3 10,20,30 more promising than pose the greatest increase in sequence.

Given the number of columns [10,20,30,1,2,3,5].

First to 10, then the time of the most promising rising sequences dp: [10].

20,dp:[10,20]

30,dp:[10,20,30]

At this new add to the mix 1, using the binary search elements, will replace the 10 1, at this time of the most promising rising sub-sequence [20, 30], you might ask, 1 in 30 of the back, and not 20 and 30 constitute a rising sequence, indeed, but we ask for is the most promising, and we are the size of the array is the length of the largest rise in sequence, if the latter can not constitute an element of a larger increase in sequence, then the current size of the array also has the largest increase in the length of the subsequence before the next record, do not worry about this point.

1,dp:[1,20,30]

2,dp:[1,2,30]

3,dp:[1,2,3]

5,dp:[1,2,3,5]

Dp at this time what we find most promising rising sequences, and its length is the length of the maximum rise sequence.

If the sequence is [10,20,30,1,2]

Dp will be seeking the last [1,2,30], but this time the size of the array, although this does not constitute a rising sequence, it is being expanded from the previous 10, 20, also holds the largest rise subsequence length.

program:

C++

//Dynamic
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        if(nums.size() == 1) return 1;
        int longest  = 0;
        vector<int> res(nums.size(), 1);
        for(int i = 1; i < nums.size(); ++i){
            for(int j = i; j > 0; j--){
                if(nums[i] > nums[j-1]){
                    res[i] = max(res[i], res[j-1]+1);
                }
            }
        }
        for(auto n:res){
            if(longest < n) longest = n;
        }
        return longest;
    }
};
//Dynamic Programming with Binary Search
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        if(nums.size() == 0) return 0;
        vector<int> res;
        res.push_back(nums[0]);
        for(int i = 1; i < nums.size(); ++i){
            int index = binarySearch(res, nums[i]);
            if(index == -1)
                res[0] = nums[i];
            else if(index < -1)
                res.push_back(nums[i]);
            else
                res[index] = nums[i];
        }
        return res.size();
    }
    int binarySearch(vector<int>& v, int num){
        if(num < v[0]) return -1;
        if(num > v[v.size()-1]) return -(v.size()+1);
        int l = 0;
        int r = v.size()-1;
        int mid;
        while(l <= r){
            mid = l + (r-l)/2;
            if(num < v[mid]) r = mid-1;
            else if(num > v[mid]) l = mid+1;
            else return mid;
        }
        return l;
    }
};

Java

//Dynamic Programming with Binary Search
class Solution {
    public int lengthOfLIS(int[] nums) {
        if(nums.length == 0) return 0;
        int[] res = new int[nums.length];
        int size = 0;
        for(int i = 0; i < nums.length; ++i){
            int index = Arrays.binarySearch(res, 0, size, nums[i]);
            if(index < 0) index = -(index+1);
            res[index] =the nums [I];
             IF (index == size) size ++ ; 
        } 
        return size; 
    } 
} 
// the Java binarySearch
 // [1] in the range of the search key, but not the elements of the array, starts counting by one, to give "- Insert point index value ";
 // [2] in the range of the search key, and an array element starts from the zero count value to obtain an index value of the search;
 // [3] of the search key is not within the range, and less than ( array) within the element, return - (+ fromIndex. 1);
 // [. 4] key is not within the search range, and greater than the range of elements (arrays), and returns - (toIndex + 1).

Guess you like

Origin www.cnblogs.com/silentteller/p/11708545.html