算法分析
-
1、如图所示,在使用最长上升子序列 I 做法时,可以发现找到长度为
1
的上升子序列,若后面的数能接到3的后面,那么一定能接到1的后面,因为1
比3
更好,扩展度高 -
2、使用
q[]
存储所有不同长度的上升子序列结尾的最小值 -
3、进来一个数
a[i]
时,通过二分在q[]
中找到最大的小于ai
的数,就能够将ai
接到该数的后面,即更新q[r + 1] = a[i]
时间复杂度 $O(nlogn)$
参考文献
参考y总
Java 代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Main {
static int N = 100010;
static int n;
static int[] a = new int[N];
static int[] q = new int[N];
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(reader.readLine().trim());
String[] s1 = reader.readLine().split(" ");
for(int i = 0;i < n;i++) a[i] = Integer.parseInt(s1[i]);
q[0] = Integer.MIN_VALUE;//可省略
int len = 0;
for(int i = 0;i < n;i++)
{
int l = 0,r = len;
while(l < r)
{
int mid = (l + r + 1) >> 1;
if(q[mid] < a[i]) l = mid;
else r = mid - 1;
}
len = Math.max(len, r + 1);
q[r + 1] = a[i];
}
System.out.println(len);
}
}
清楚
在二分查找时,如果a[i]比最后一个小于a[i]的值a[k]大,且 k < i,即a[i]是在a[k]的右边,这时候这样更新q合理吗?
比如 3 1 2 -1序列,原先当i = 1时,q[1] = 1,i = 2时q[2] = 2,那么当i = 3时,q[1]是应该更新为-1吗?这样长度为1的最小值为-1反而在长度为2的最小值2的后面?感觉很奇怪,是怎么理解的?
这里是更新后面的数而不是更新1,就比如1,2后面的数要为-1我觉得要更新条件是比1大,比2小的数,而且是更新1后面的数,而不是更新1,hh
dalao
不是大佬,互相学习hh