leetcode 300. Longest Increasing Subsequence

257 篇文章 17 订阅

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?

这道题还算简单。

我使用 DP[i] 来存储:在 i 之前比DP[i]小的数 的个数,当然还要加上 DP[i] 本身的1。如 [2,3,5,1],dp[0]=1, dp[2]=3。

public int lengthOfLIS(int[] nums) {
	int maxLength=0;
	int[] DP=new int[nums.length];
	for(int i=0;i<nums.length;i++){
		DP[i]=1;
		for(int j=0;j<i;j++){
			if(nums[j]<nums[i]){
				DP[i]=Math.max(DP[i],DP[j]+1);
			}
		}
		if(DP[i]>maxLength){
			maxLength=DP[i];
		}
	}
	return maxLength;
}
这道题有solutions: https://leetcode.com/problems/longest-increasing-subsequence/solution/

Approach #3 Dynamic Programming [Accepted]

Algorithm

dp[i]dp[i] 存储以nums[i结尾的最长递增子序列的长度。

dp[i] = \text{max}(dp[j]) + 1, \forall 0\leq j < idp[i]=max(dp[j])+∀ 0j<i

最后, dp[i]dp[i 的最大值就是我们需要的结果。

LIS_{length}= \text{max}(dp[i]), \forall 0\leq i < nLISlength=max(dp[i]∀ 0i<n

Java

public class Solution {
    public int lengthOfLIS(int[] nums) {
        if (nums.length == 0) {
            return 0;
        }
        int[] dp = new int[nums.length];
        dp[0] = 1;
        int maxans = 1;
        for (int i = 1; i < dp.length; i++) {
            int maxval = 0;
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j]) {
                    maxval = Math.max(maxval, dp[j]);
                }
            }
            dp[i] = maxval + 1;
            maxans = Math.max(maxans, dp[i]);
        }
        return maxans;
    }
}

Complexity Analysis

  • Time complexity : O(n^2)O(n2). Two loops of nn are there.

  • Space complexity : O(n)O(n)dpdp array of size nn is used.


Approach #4 Dynamic Programming with Binary Search[Accepted]:

Algorithm

同样也使用DP。从左到右遍历数组,DP数组存储 包含当前遇到元素的递增子序列。当遍历数组时,使用迄今为止遇到的元素来填充DP数组。比如,当前遇到的元素是 the j^{th}jth index (nums[j]nums[j]), 我们需要使用二分查找来考虑它在DP数组中的正确位置(say i^{th}ith index) ,可以用二分查找是因为DP数组存储的是递增子序列。使用 lenlen 来记录DP的长度。 DP不一定结果是最长递增子序列,但是DP的长度会是最长子序列的长度。len = len + 1

比如这个例子:

input: [0, 8, 4, 12, 2]

dp: [0]

dp: [0, 8]

dp: [0, 4]

dp: [0, 4, 12]

dp: [0 , 2, 12] which is not the longest increasing subsequence, but length of dpdp array results in length of Longest Increasing Subsequence.

更详细的解释见:http://www.geeksforgeeks.org/longest-monotonically-increasing-subsequence-size-n-log-n/

Java

public class Solution {
    public int lengthOfLIS(int[] nums) {
        int[] dp = new int[nums.length];
        int len = 0;
        for (int num : nums) {
            int i = Arrays.binarySearch(dp, 0, len, num);
            if (i < 0) {
                i = -(i + 1);
            }
            dp[i] = num;
            if (i == len) {
                len++;
            }
        }
        return len;
    }
}

注意: Arrays.binarySearch() 返回 search key 的索引。如果它不在array中,返回 (-(insertion point) - 1) 。(The insertion point 指如果它要被插进数组中,应当插入的那个索引,即当前数组中第一个比它大的值的index。如果数组中所有元素都比它小,就是数组的长度)。

Complexity Analysis

  • Time complexity : O(nlog(n))O(nlog(n)). Binary search takes log(n)log(n) time and it is called nn times.

  • Space complexity : O(n)O(n)dpdp array of size nn is used.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值