300. Longest Increasing Subsequence

Description

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?

Credits:
Special thanks to @pbrother for adding this problem and creating all test cases.

Solution

DP, time O(n ^ 2), space O(n)

class Solution {
    public int lengthOfLIS(int[] nums) {
        if (nums == null || nums.length < 1) {
            return 0;
        }
        
        int longest = 0;
        int n = nums.length;
        int[] lis = new int[n];     // the length of lis ended with nums[i]
        
        for (int i = 0; i < n; ++i) {
            lis[i] = 1;
            for (int j = 0; j < i; ++j) {
                if (nums[i] > nums[j]) {
                    lis[i] = Math.max(lis[i], lis[j] + 1);
                }
            }
            longest = Math.max(longest, lis[i]);
        }
        
        return longest;
    }
}

Binary search, time O(nlogn), space O(n)

蛮经典的思路,用一个数组minTail存储每个lis length对应的最小结尾元素。然后对于nums中的每个n,二分查找minTail,并更新minTail即可。

class Solution {
    public int lengthOfLIS(int[] nums) {
        if (nums == null || nums.length < 1) {
            return 0;
        }
        
        int[] minTail = new int[nums.length];
        int tailPos = -1;
        
        for (int i = 0; i < nums.length; ++i) {
            int j = search(minTail, 0, tailPos, nums[i]);
            minTail[j] = nums[i];
            tailPos = Math.max(tailPos, j);
        }
        
        return tailPos + 1;
    }
    
    // find the first element larger than or equal to target
    public int search(int[] nums, int left, int right, int target) {
        while (left <= right) {
            int mid = left + (right - left) / 2;
            
            if (nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        
        return left;
    }
}

你可能感兴趣的:(300. Longest Increasing Subsequence)