300. Longest Increasing Subsequence

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?

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

class Solution {
    public int lengthOfLIS(int[] nums) {
        int n = nums.length;
        int[] dp = new int[n]; //always store the ascending sequence
        int res = 0;
        
        for(int num : nums) {
            int i = Arrays.binarySearch(dp, 0, res, num);
            i = i < 0 ? -(i + 1) : i;
            dp[i] = num;
            res = i == res ? ++res : res;
        }
        return res;
    }
}

https://www.youtube.com/watch?v=YoeWZ3ELMEk

还有这么一种奇淫巧计,用的bianry search,为O(nlogn),首先介绍 Arrays.binarySearch(int[] a, int fromIndex, int toIndex, int key),

如果找到了就返回index,找不到就返回a == -("i" + 1),这个i是本应该插入的位置,那我们反过来求i就是-(a + 1) == i

举个例子啊【70, 40, 60, 10, 20, 30, 4, 5, 6, 7】

dp数组存放到index i时的longest increasing subsequence, 对应的元素放到对应的index中

开始

70,res = 1

40, 替换70,res = 1

60,res = 2,变成【40,60】

10,res = 2,【10,60】

20,res = 2,【10,20】

30,查找返回的i == 2 == res,然后++res = 3,【10,20,30】

4,res = 3,【4,20,30】

5,res = 3,【4,5,30】

6,res = 3,【4,5,6】

7,查找返回的i == 3 == res,然后++res = 4,【4,5,6,7】

得到res = 4

class Solution {
    public int lengthOfLIS(int[] nums) {
        int n = nums.length;
        int[] dp = new int[n]; //always store the ascending sequence
        int res = 0;
        Arrays.fill(dp, Integer.MAX_VALUE);
        
        for(int i = 0; i < n; i++) {
            int x = binarySearchPosition(dp, nums[i], i);
            dp[x] = nums[i];
        }
        for(int i = n - 1; i >= 0; i--) {
            if(dp[i] != Integer.MAX_VALUE) return i + 1;
        }
        return n == 0 ? 0 : 1;
    }
     private int binarySearchPosition(int[] dp,int target,int hi){
            int low = 0;
            while(low <= hi){
                int mid = low + (hi - low)/2;
                if(target == dp[mid]) return mid;
                else if(target < dp[mid]) hi = mid - 1;
                else if(target > dp[mid]) low = mid + 1;
            }
            return low;
        }
}

用自制binarysearch方法,需要先Arrays.fill(dp, Integer.MAX_VALUE), 而且search的时候要把i作为end index传入

原文地址:https://www.cnblogs.com/wentiliangkaihua/p/11601660.html