最长上升子序列(LIS)长度
方法一、动态规划方法 时间复杂度为 O(n2) O ( n 2 )
public class Solution {
public int lis(int[] nums) {
if(nums.length==0){
return 0;
}
int dp[]=new int[nums.length];
for(int i=0;i<nums.length;i++){
dp[i]=1;
for(int j=0;j<i;j++){
if(nums[i]>nums[j]&&dp[j]+1>dp[i])
dp[i]=dp[j]+1;
}
}
int max=Integer.MIN_VALUE;
for(int i=0;i<nums.length;i++){
max=Math.max(max, dp[i]);
}
return max;
}
}
方法二、时间复杂度为 O(nlog(n)) O ( n l o g ( n ) )
import java.util.*;
public class Main {
static int[] arr;
static int[] ans;
static int index;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
arr = new int[n];
ans = new int[n];
for(int i = 0; i < n; i++){
arr[i] = sc.nextInt();
}
ans[0] = arr[0];
index = 0;
for(int i = 1; i < n; i++){
if(arr[i] > ans[index]){
ans[++index] = arr[i];
} else {
int pos = binary_search(i);
ans[pos] = arr[i];
}
}
System.out.println(index + 1);
}
public static int binary_search(int i){
int left = 0, right = index, mid;
while(left < right){
mid = left + (right - left) / 2;
if(ans[mid] == arr[i]){
return mid;
} else if(ans[mid] > arr[i]){
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
}
详细方案参考: 最长上升子序列(LIS)长度的O(nlogn)算法
最长公共子序列(LCS) 动态规划解法
import java.util.*;
import java.lang.*;
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String x = sc.next();
String y = sc.next();
getLCS(x,y);
}
public static void getLCS(String x, String y){
char[] s1 = x.toCharArray();
char[] s2 = y.toCharArray();
//此处的棋盘长度要比字符串长度多加1,需要多存储一行0和一列0
int[][] array = new int[x.length()+1][y.length()+1];
for(int j = 0; j < array[0].length; j++){//第0行第j列全部赋值为0
array[0][j] = 0;
}
for(int i = 0; i < array.length; i++){//第i行,第0列全部为0
array[i][0] = 0;
}
for(int m = 1; m < array.length; m++){//利用动态规划将数组赋满值
for(int n = 1; n < array[m].length; n++){
if(s1[m - 1] == s2[n - 1]){
array[m][n] = array[m-1][n-1] + 1;//动态规划公式一
}else{
array[m][n] = Math.max(array[m -1][n], array[m][n -1]);//动态规划公式二
}
}
}
Stack<Character> stack = new Stack<>();
int i = x.length() - 1;
int j = y.length() - 1;
while((i >= 0) && (j >= 0)){
if(s1[i] == s2[j]){//字符串从后开始遍历,如若相等,则存入栈中
stack.push(s1[i]);
i--;
j--;
}else{
//如果字符串的字符不同,则在数组中找相同的字符
//注意:数组的行列要比字符串中字符的个数大1,因此i和j要各加1
if(array[i+1][j] > array[i][j+1]){
j--;
}else{
i--;
}
}
}
while(!stack.isEmpty()){//打印输出栈正好是正向输出最大的公共子序列
System.out.print(stack.pop());
}
}
}