Given an unsorted array of integers, find the length of longest increasing subsequence.
Example:
Input:[10,9,2,5,3,7,101,18]
Output: 4 Explanation: The longest increasing subsequence is[2,3,7,101]
, therefore the length is4
.
Note:
- There may be more than one LIS combination, it is only necessary for you to return the length.
- Your algorithm should run in O(n2) complexity.
Follow up: Could you improve it to O(n log n) time complexity?
class Solution { public int lengthOfLIS(int[] nums) { int l = nums.length; if(l == 0) return 0; int[] f = new int[l]; int res = 1; Arrays.fill(f,1); for(int j = 1; j < l; j++){ for(int i = 0; i < j; i++){ if(nums[j] > nums[i]){ f[j] = Math.max(f[j], f[i] + 1); } } res = Math.max(res, f[j]); } return res; } }
class Solution { public int lengthOfLIS(int[] nums) { int n = nums.length; int[] dp = new int[n]; //always store the ascending sequence int res = 0; for(int num : nums) { int i = Arrays.binarySearch(dp, 0, res, num); i = i < 0 ? -(i + 1) : i; dp[i] = num; res = i == res ? ++res : res; } return res; } }
https://www.youtube.com/watch?v=YoeWZ3ELMEk
还有这么一种奇淫巧计,用的bianry search,为O(nlogn),首先介绍 Arrays.binarySearch(int[] a, int fromIndex, int toIndex, int key),
如果找到了就返回index,找不到就返回a == -("i" + 1),这个i是本应该插入的位置,那我们反过来求i就是-(a + 1) == i
举个例子啊【70, 40, 60, 10, 20, 30, 4, 5, 6, 7】
dp数组存放到index i时的longest increasing subsequence, 对应的元素放到对应的index中
开始
70,res = 1
40, 替换70,res = 1
60,res = 2,变成【40,60】
10,res = 2,【10,60】
20,res = 2,【10,20】
30,查找返回的i == 2 == res,然后++res = 3,【10,20,30】
4,res = 3,【4,20,30】
5,res = 3,【4,5,30】
6,res = 3,【4,5,6】
7,查找返回的i == 3 == res,然后++res = 4,【4,5,6,7】
得到res = 4
class Solution { public int lengthOfLIS(int[] nums) { int n = nums.length; int[] dp = new int[n]; //always store the ascending sequence int res = 0; Arrays.fill(dp, Integer.MAX_VALUE); for(int i = 0; i < n; i++) { int x = binarySearchPosition(dp, nums[i], i); dp[x] = nums[i]; } for(int i = n - 1; i >= 0; i--) { if(dp[i] != Integer.MAX_VALUE) return i + 1; } return n == 0 ? 0 : 1; } private int binarySearchPosition(int[] dp,int target,int hi){ int low = 0; while(low <= hi){ int mid = low + (hi - low)/2; if(target == dp[mid]) return mid; else if(target < dp[mid]) hi = mid - 1; else if(target > dp[mid]) low = mid + 1; } return low; } }
用自制binarysearch方法,需要先Arrays.fill(dp, Integer.MAX_VALUE), 而且search的时候要把i作为end index传入