题目描述:
给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入:[10,9,2,5,3,7,101,18]
输出: 4 解释: 最长的上升子序列是[2,3,7,101],
它的长度是4
说明:
- 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
- 你算法的时间复杂度应该为 O(n2) 。
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?
动态规划:
动态规划:遍历第i个元素时,如果nums[i]比前面第j个数大,那包含第i个元素的最长
上升子序列一定是包含第j元素的,如果i前面有很多个比nums[i]小的数,那包含i的最
长上升子序列一定是包含前面这些比nums[i]小的某个数,也可能是很多个数,也可能
是全部包含比nums[i]小的数。比如[2,5,3,7]在比较7时,前面的2,5,3都比7小,但
是dp[3]只能是3(2,5,7/2,3,7)。所以这个公式表示就是
dp[i]=max(dp[j])+1;(0<=j<i)。
最后选择dp最大的数就是整个数组最长上升子序列长度。
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
vector<int>dp(nums.size(),1);
if(nums.size()==0)
return 0;
int i,j,Max=1;
for(i=1;i<nums.size();i++)
{
for(j=0;j<i;j++)
if(nums[i]>nums[j])
dp[i]=max(dp[i],dp[j]+1);
Max=max(Max,dp[i]);
}
return Max;
}
};
class Solution {
public int lengthOfLIS(int[] nums) {
if(nums==null||nums.length==0){return 0;}
int[] dp=new int[nums.length];
dp[0]=1;
int maxlen=1;
for(int i=1;i<nums.length;i++){
int maxval=0;
for(int j=0;j<i;j++){
if(nums[i]>nums[j]){
maxval=Math.max(dp[j],maxval);
}//如果前面j都没有比i数小的数,那么包含i的序列只能从i开始,dp[i]=1
}
dp[i]=maxval+1;
maxlen=Math.max(maxlen,dp[i]);//随时更新最大的dp值
}
return maxlen;
}
}