对于一个数字序列,请设计一个复杂度为O(nlogn)的算法,返回该序列的最长上升子序列的长度,这里的子序列定义为这样一个序列U1,U2...,其中Ui < Ui+1,且A[Ui] < A[Ui+1]。
给定一个数字序列A及序列的长度n,请返回最长上升子序列的长度。
测试样例:
[2,1,4,3,1,5,6],7
返回:4
//这个题其实找的是索引
import java.util.*;
public class AscentSequence {
public int findLongest(int[] A, int n) {
// write code here
//循环每个数字
int max;
int count;
int maxLen=1;
for(int i=0;i<A.length-1;i++){
count=1;
max=A[i];
for(int j=i+1;j<A.length;j++){
if(A[j]>max){
count++;
max=A[j];
}
}
maxLen=Math.max(count,maxLen);
}
return maxLen;
}
}
为何只通过20%
//找到了原因。以下动态规划通过全部
/*
要求长度为i以前的序列,以i-1结尾的是多少呢?dp[i]表示A[i-1]以前的子序列
*/
/*
* 203,39,186
* dp0:0
dp1:1
dp2:1
dp3:1显然应该是2.但是如果和前边最大的比较,还是1
* */
/*
* dp[i]表示以第i个元素结尾(A[i])递增子序列个数
* 初始化dp[i]=0;
* dp[i]=max(dp[j])+1 (j=0,1,2..i-1)where A[i]>A[j]
* */
/*
要求长度为i以前的序列,以i-1结尾的是多少呢?dp[i]表示A[i-1]以前的子序列
*/
import java.util.*;
public class AscentSequence {
public int findLongest(int[] A, int n) {
int[] dp = new int[n];
for(int i=0;i<A.length;i++){
dp[i]=1;
}
int max=1;
for(int i=1;i<A.length;i++){
for(int j=0;j<i;j++){
if(A[i]>A[j]){
dp[i]=Math.max(dp[j]+1,dp[i]);//取的是dp[j]+1中的最大的
}
}
max = Math.max(max, dp[i]);
}
return max;
}
}
import java.util.*;
public class AscentSequence {
public int findLongest(int[] A, int n) {
// write code here
int[] dp=new int[n];
int[] ends=new int[n];
ends[0]=A[0];
dp[0]=1;
int max=1;
int r=0,right=0,l=0,m=0;
for(int i=1;i<n;i++){
l=0;
r=right;
while(l<=r){
m=(l+r)/2;
if(A[i]>ends[m]){
l=m+1;
}else{
r=m-1;
}
}
//没明白
right=Math.max(l,right);
ends[l]=A[i];
dp[i]=l+1;
max=Math.max(dp[i],max);
}
return max;
}
}
左老师亲传,不过还没有太明白
import java.util.*;
public class AscentSequence {
public int findLongest(int[] A, int n) {
int[] dp = new int[n];
Arrays.fill(dp, 1);
for (int i = 1; i < dp.length; i ++ ) {
int max = 0;
for (int j = i - 1; j >= 0; j -- ) {
if(A[i] > A[j] && max < dp[j]) {
max = dp[j];
dp[i] = dp[j] + 1;
}
}
}
int res = 0;
for (int i:dp) {
res = res > i ? res : i;
}
return res;
}
}
import java.util.*;
public class AscentSequence {
public int findLongest(int[] A, int n) {
// write code here
int[] dp = new int[n];
int max = Integer.MIN_VALUE;
for (int i = 0; i < n; ++i) {
if (i == 0) {
dp[i] = 1;
} else {
dp[i] = 1;
for (int j = i - 1; j >= 0; --j) {
if (A[j] < A[i]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
}
max = Math.max(dp[i], max);
}
return max;
}
}