输出两行,第一行包括一个正整数n(n<=100000),代表数组长度。第二行包括n个整数,代表数组arr。
输出一行。代表你求出的最长的递增子序列。
9 2 1 5 3 6 4 8 9 7
1 3 4 8 9
5 1 2 8 6 4
1 2 4
其最长递增子序列有3个,(1,2,8)、(1,2,6)、(1,2,4)其中第三个字典序最小,故答案为(1,2,4)
时间复杂度,空间复杂度
。
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); String[] strArr = br.readLine().split(" "); int[] arr = new int[n]; for(int i = 0; i < n; i++){ arr[i] = Integer.parseInt(strArr[i]); } int[] dp = new int[n]; int[] ends = new int[n]; dp[0] = 1; ends[0] = arr[0]; int tail = 0; // 有效区域末尾 int maxLen = 1, maxIdx = 0; // 最长递增子序列长度和index for(int i = 1; i < n; i++){ int index = lowerbound(ends, 0, tail, arr[i]); dp[i] = index + 1; // 以i结尾的最长递增子序列长度为index+1 ends[index] = arr[i]; if(index > tail){ tail++; // 有效区扩充 } if(dp[i] >= maxLen){ maxLen = dp[i]; maxIdx = i; } } // 还原字典序最小的最长递增子序列 int[] increasingSeq = new int[maxLen]; for(int i = maxIdx; i >= 0; i--){ // 从后往前更新,遇到递增子序列长度为maxLen的arr[i]就更新结尾位置,然后把maxLen缩短 if(dp[i] == maxLen){ increasingSeq[--maxLen] = arr[i]; } } for(int i = 0; i < increasingSeq.length; i++){ System.out.print(increasingSeq[i] + " "); } } private static int lowerbound(int[] arr, int L, int R, int target) { int left = L, right = R; int index = R + 1; while(left <= right){ int mid = left + ((right - left) >> 1); if(arr[mid] < target){ left = mid + 1; }else{ index = mid; right = mid - 1; } } return index; } }