import java.util.*; /** * NC91 最长上升子序列(三) * @author d3y1 */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * retrun the longest increasing subsequence * @param arr int整型一维数组 the array * @return int整型一维数组 */ public int[] LIS (int[] arr) { return solution(arr); } /** * 二分 * @param arr * @return */ private int[] solution(int[] arr){ int n = arr.length; // 表示从前面到以第i个数字结尾的最长上升子序列的长度(arr[i]必须被选取) int[] dp = new int[n]; // 最长上升子序列 单调增 int[] seq = new int[n]; // init seq[0] = arr[0]; dp[0] = 1; // 最长上升子序列最大索引(最右索引) int index = 0; // 当前元素arr[i]插入seq位置 int pos; int left,right,mid; for(int i=1; i<n; i++){ if(seq[index] < arr[i]){ index++; pos = index; seq[pos] = arr[i]; dp[i] = pos+1; } // 二分 else{ left = 0; right = index; while(left <= right){ mid = (left+right)/2; if(seq[mid] < arr[i]){ left = mid + 1; }else{ right = mid - 1; } } pos = left; seq[pos] = arr[i]; dp[i] = pos+1; index = Math.max(index, pos); } } // 最长上升子序列的长度 int max = index+1; int[] result = new int[max]; for(int i=n-1,j=max; j>0; i--){ if(dp[i] == j){ result[--j] = arr[i]; } } return result; } }