问题描述
给定一个序列,求解它的最长递增子序列的长度。比如:给定序列[10, 9, 2, 5, 3, 7, 101, 18],它的最长递增子序列是[2, 3, 7, 101],所以最长递增子序列的长度为4。最长递增子序列的组合方式可能不唯一,只需要返回其长度。
请编写一个程序,实现上述功能。(可以考虑不同的时间复杂度实现,比如O(n^2)和O(nlogn)等,注意清橙上判断输入结束用EOF,提交时用'\n')
输入格式
输入一个整数序列。(输入序列长度不超过100)
输出格式
最长递增子序列长度。
样例输入
样例输出
解题思路:
最长递增子序列问题,动态规划:n^2,贪心+二分:nlongn
最长递增子序列说明https://blog.csdn.net/weixin_48898946/article/details/122790761
java代码:(动态规划)
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] split = br.readLine().split(" ");
int []arr = new int[split.length];//存放原始序列
for(int i = 0; i < split.length; i++) {
arr[i] = Integer.parseInt(split[i]);
}
int []dp = new int[arr.length];//dp数组
for(int i = 0; i < arr.length; i++) {
dp[i] = 1;//初始化dp,即本身的长度1
for(int j = 0; j < i; j++) {
if(arr[j] < arr[i]) {
dp[i] = Math.max(dp[i], dp[j] + 1);//当前的长度与之前小于当前数加一的最大值作为dp值
}
}
}
int ans = dp[0];//存放dp数组中的最大值
for(int i = 0; i < dp.length; i++) {
if(dp[i] > ans)
ans = dp[i];
}
System.out.println(ans);
}
}
提交截图:
java代码:(贪心+二分)
import java.io.*;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] split = br.readLine().split(" ");
int []arr = new int[split.length];
for(int i = 0; i < split.length; i++) {
arr[i] = Integer.parseInt(split[i]);
}
int []dp = new int[arr.length];
int len = 0;//dp数组中“有意义”的元素个数
for(int i = 0; i < arr.length; i++) {
int index = Arrays.binarySearch(dp, 0, len, arr[i]);//二分查找
if(index < 0) {//返回索引为负值,即原数组中不存在
index = -(index + 1);//更新为期待位置
}
dp[index] = arr[i];//替换或追加
if(index == len)len++;//扩大二分位置
}
System.out.println(len);
}
}
提交截图: