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(n^2) complexity.


对于一个递增子序列,想要增加它的长度,就必须在尾部添加一个更大的值。
O(n^2)
dp[i]表示以nums[i]结尾的最长递增序列的长度。长度增加的条件就是一个数字比nums[i]大。

public int lengthOfLIS(int[] nums) {
        int N = nums.length;
        if (N == 0) return 0;
        int[] dp = new int[N];
        Arrays.fill(dp, 1);
        int res = 1;
        for (int i = 1; i < N; i++) {
            for (int j = 0; j < i; j++) {
                if (nums[j] < nums[i]) {
                    dp[i] = Math.max(dp[j] + 1, dp[i]);
                }
            }
            res = Math.max(res, dp[i]);
        }
        return res;
    }

O(nlogn)
长度最大值即为输入数组的长度。用dp[i]表示,长度为i时,结尾的数字。可以不断更新。这里可以用binarySearch来查询需要插放的位置。
Java自带的binarySearch,如果有该元素则返回正确的index,如果没有返回-(index+1),是一个负数,我们需要替换成正确的数值。

public class Solution {
    public int lengthOfLIS(int[] nums) {            
        int[] dp = new int[nums.length];
        int len = 0;

        for(int x : nums) {
            int i = Arrays.binarySearch(dp, 0, len, x);
            if(i < 0) i = -(i + 1);
            dp[i] = x;
            if(i == len) len++;
        }

        return len;
    }
}

大米中的大米
12 声望5 粉丝

你的code是面向面试编程的,收集和整理leetcode discussion里个人认为的最优且最符合我个人思维逻辑的解法。