问题:
给定一个整数数组(下标从 0 到 n-1, n 表示整个数组的规模),请找出该数组中的最长上升连续子序列。(最长上升连续子序列可以定义为从右到左或从左到右的序列。)
比如:
给定 [5, 4, 2, 1, 3], 其最长上升连续子序列(LICS)为 [5, 4, 2, 1], 返回 4.
给定 [5, 1, 2, 3, 4], 其最长上升连续子序列(LICS)为 [1, 2, 3, 4], 返回 4.
分析:
递推关系式如何确定?f(i) 表示前i个数字中 最长上升子序列的长度,注意,其所包含的最长连续上升子序列未必是以i结尾的。因此思路来了。令dp[i]表示以以i结尾的连续上升子序列长度,
dp[i] = (A[i]>A[i-1])?dp[i-1]+1:1,局部是贪心的。开一个全局变量记录局部遍历的最大值即可。注意顺序 逆序两种情况,可以放在同一个循环中处理。
代码:
int longestIncreasingContinuousSubsequence(vector<int>& A) {
// Write your code here
int n = A.size();
if(n<1){
return 0;
}
if(n<2){
return 1;
}
//开两个数组存储之前状态
vector<int> dp1(n,1);
vector<int> dp2(n,1);
dp1[0] = dp2[0]=1;
int glomax=0;
for(int i=1;i<n;i++){
dp1[i] = (A[i]>A[i-1])?dp1[i-1]+1:1;
dp2[i] = (A[i]<A[i-1])?dp2[i-1]+1:1;
glomax = max(glomax,max(dp1[i],dp2[i]));
}
return glomax;
}
事实上,根据状态依赖关系,O(n)空间复杂度依然可以省掉
int longestIncreasingContinuousSubsequence(vector<int>& A) {
// Write your code here
int n = A.size();
if(n<1){
return 0;
}
if(n<2){
return 1;
}
int dp1=1,dp2=1;
int glomax=0;
for(int i=1;i<n;i++){
dp1 = (A[i]>A[i-1])?dp1+1:1;
dp2 = (A[i]<A[i-1])?dp2+1:1;
glomax = max(glomax,max(dp1,dp2));
}
return glomax;
}