300. Longest Increasing Subsequence
Description Submission Solutions Add to List
- Total Accepted: 64115
- Total Submissions: 170859
- Difficulty: Medium
- Contributors: Admin
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?
【题目分析】
给定一个无序的整数数组序列,找出序列中最长的增序的子序列。
例如[10, 9, 2, 5, 3, 7, 101, 18]这个序列中出现的最长的增序的子序列为:[2, 3, 7, 101]。
【思路】
1. 用动态规划的思路来解决。
用dp[i]来表示如果子序列是以第i个数结尾,那么此时最长的子序列的长度。
动态规划的表达式如下:
dp[i] = max(dp[j]) + 1, 0 =< j < i, dp[i] > dp[j]
此时代码的时间复杂度为O(N2), 空间复杂度为O(N)。还有没有改进的空间呢?
2.
The basic idea is present in the majority of solutions shared for this task, I have only tried to implement it in a manner as concise as possible without damaging the code readability.
The idea is that as you iterate the sequence, you keep track of the minimum value a subsequence of given length might end with, for all so far possible subsequence lengths. So dp[i] is the minimum value a subsequence of length i+1 might end with. Having this info, for each new number we iterate to, we can determine the longest subsequence where it can be appended using binary search. The final answer is the length of the longest subsequence we found so far.
这个方法是在讨论区看到的,同样的方法在:http://blog.csdn.net/jiary5201314/article/details/51169602
递增序列是一个增序的序列,我们找到这个序列中某个位置可能出现的最小值。因此dp[i]表示的是长度为i+1的子序列结尾的最小值。遍历数组中的每一个元素,我们可以在dp[i]中找到它的插入位置,查找位置的过程是一个二分查找的过程,使用二分查找算法可以明显降低算法的时间复杂度。算法的时间复杂度降低为O(NlogN),提交两次结果,发现第二种方法的效果明显好于第一种方法。
【java代码1】
1 public class Solution { 2 public int lengthOfLIS(int[] nums) { 3 if(nums.length == 0) return 0; 4 5 int dp[] = new int[nums.length]; 6 for(int i = 0; i < nums.length; i++) { 7 dp[i] = 1; 8 } 9 int max = 1; 10 11 for(int i = 1; i < nums.length; i++) { 12 for(int j = 0; j < i; j++) { 13 if(nums[i] > nums[j] && dp[j]+1 > dp[i]) { 14 dp[i] = dp[j] + 1; 15 max = Math.max(max, dp[i]); 16 } 17 } 18 } 19 20 return max; 21 } 22 }
【java代码2】
1 public class Solution { 2 public int lengthOfLIS(int[] nums) { 3 int[] dp = new int[nums.length]; 4 int len = 0; 5 6 for(int x : nums) { 7 int i = Arrays.binarySearch(dp, 0, len, x); 8 if(i < 0) i = -(i+1); 9 dp[i] = x; 10 if(i == len) len++; 11 } 12 13 return len; 14 } 15 }