LC300. Longest Increasing Subsequence

not necessarily continuous

Posted by freeCookie🍪 on December 27, 2016

Question

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?

Naive solution: O(n^2)

res[i]代表i下标结尾的最长LIS。对于res[i],如果num[i] > num[j] (j < i), res[i] 为满足此条件的res[j] + 1, 每一步取最优。

public class Solution {
    public int lengthOfLIS(int[] nums) {
        if(nums.length == 0) {
            return 0;
        }
        int[] res = new int[nums.length+1];
        res[0] = 1;
        int index = 1;
        for(int i = 1; i < nums.length; i++) {
            int max = 1;
            for(int j = 0; j < i; j++) {
                if(nums[i] > nums[j]) {
                    max = Math.max(max, res[j]+1);
                }
            }
            res[i] = max;
            index = Math.max(index, res[i]);
        } // for i
        return index;
    } // lengthOfInt
}
O(nlgn) solution:

低卡百事大神的解法

对i属于(1, nums.length], tails代表长度为i的LIS最小的末尾。对每个num二分查找更新tails的位置,如果num大于存在于tails的所有末尾值则size++。怎么什么都会🙄

public class Solution {
    // tails[] means for each length = i LIS, the min tail of it
    // for each num, binary search in tails[]
    // if it is larger than tails[end], size++
    // else in tails, find the right update place
    // O(nlgn)
    public int lengthOfLIS(int[] nums) {
        int tails[] = new int[nums.length];
        int size = 0; 
        for(int num: nums){
            int begin = 0, end = size; 
            // find m when tail[m-1] < mid < tail[m]
            while(begin < end){
                int mid = (begin + end)/2;
                if(tails[mid] < num){
                    begin = mid + 1;
                }else{
                    end = mid;
                }
            }
            tails[begin] = num;
            if(begin == size)   size++;
        }
        return size;
    }
}