Longest Increasing Subsequence -- Leetcode

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

For example,
Given [10, 9, 2, 5, 3, 7, 101, 18],
The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that 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?


算法一,動態規劃

O(n*n) 在leetcode上實際執行時間爲188ms

從左到右依次確定每個元素的LIS。

在確定當前元素的LIS,需要與左面的元素依次作比較:

如果左面的元素小於當前元素,則當前元素的LIS爲左面的元素LIS+1;相等,則LIS與之相等。

取其最大值爲當前元素的LIS值。

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int> lengths(nums.size(), 1);
        int max_length = 0;
        for (size_t i=0; i<nums.size(); ++i) {
            for (int j=i-1; j>=0; --j) {
                if (nums[j] < nums[i])
                    lengths[i] = max(lengths[i], lengths[j]+1);
                else if (nums[j] == nums[i])
                    lengths[i] = max(lengths[i], lengths[j]);
            }
            
            max_length = max(max_length, lengths[i]);
        }
        
        return max_length;
    }
};



算法二,

O(n log n), 在leetcode上執行時間爲4ms。

維持一個潛在的LIS隊列,

在隊列中進行折半查找。找到滿足>=當前值,隊列中最小元素。即左邊界。執行替換。

注意,這個隊列,並不一定是合法的LIS。

但長度一定是對的,而且最後一個元素也是對的。


class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int> seq;
        for (auto i: nums) {
            auto iter = lower_bound(seq.begin(), seq.end(), i);
            if (iter == seq.end())
                seq.push_back(i);
            else
                *iter = i;
        }
        
        return seq.size();
    }
};
算法來源:http://www.geeksforgeeks.org/longest-monotonically-increasing-subsequence-size-n-log-n/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章