package class090; // 本题测试链接 : https://leetcode.com/problems/longest-increasing-subsequence public class Code01_LIS { // // O(N^2) // // 不够好 // public static int lisMaxLen1(int[] arr) { // if (arr == null || arr.length == 0) { // return 0; // } // int n = arr.length; // int[] dp = new int[n]; // dp[0] = 1; // int max = dp[0]; // for (int i = 1; i < n; i++) { // int pre = 0; // for (int j = 0; j < i; j++) { // if (arr[j] < arr[i]) { // pre = Math.max(pre, dp[j]); // } // } // dp[i] = pre + 1; // max = Math.max(max, dp[i]); // } // return max; // } // // public static int lisMaxLen2(int[] arr) { // if (arr == null || arr.length == 0) { // return 0; // } // int n = arr.length; // int[] dp = new int[n]; // int[] ends = new int[n]; // dp[0] = 1; // ends[0] = arr[0]; // // ends数组,有效区 // // ends = 1.... // // 0...validSize-1 范围上去二分! // int validSize = 1; // int max = dp[0]; // for (int i = 1; i < n; i++) { // int cur = arr[i]; // int endsi = find(ends, validSize, cur); // if(endsi == -1) { // ends数组有效区里,都是 < num // ends[validSize++] = cur; // dp[i] = validSize; // } else { // 查找>=num最左的位置,找到了! // ends[endsi] = cur; // dp[i] = endsi + 1; // } // max = Math.max(max, dp[i]); // } // return max; // } // // // 在ends数组有效区里,查找>=num最左的位置 // // 如果没有>=num最左的位置,返回-1 // public static int find(int[] ends, int size, int num) { // // } // 最优解! public static int lengthOfLIS(int[] arr) { if (arr == null || arr.length == 0) { return 0; } int[] ends = new int[arr.length]; ends[0] = arr[0]; int right = 0; int l = 0; int r = 0; int m = 0; int max = 1; for (int i = 1; i < arr.length; i++) { l = 0; r = right; while (l <= r) { m = (l + r) / 2; if (arr[i] > ends[m]) { l = m + 1; } else { r = m - 1; } } right = Math.max(right, l); ends[l] = arr[i]; max = Math.max(max, l + 1); } return max; } }