Title:
Given an unsorted array of integers, find the length of longest increasing subsequence.
For example,
Given [10, 9, 2, 5, 3, 7, 101, 18],
The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that 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?
This question is to ask for the maximum length of the incremental part of an array. At first glance, there is no idea about this topic. How can we translate the incremental part into the language that the program can express? The main problem is that if the latter element is more clever than the former one in how to deal with it in an hour, it's really clever to see the solution of others later. It turns the problem into an unspeakable thing= Well, I don't know what other people think anyway. The code is as follows:
public static int lengthOfLIS(int[] nums) {
//Used to store the current incremental array, initialized to all 0
int [] res = new int[nums.length];
int len = 0;
//Find the appropriate insertion location for each element in nums
for(int x:nums){
//Use a binary search to find the location index where x should be inserted, and return the negative value of low+1 if there are no equal elements
int i = Arrays.binarySearch(res, 0, len, x);
//Convert to positive
if(i < 0) i = -(i+1);
//Insert x into the corresponding position, and note that if x is smaller than the previous element, it is replaced here.
res[i] = x;
//Len holds the current maximum incremental array length and only adds one operation if i equals len.
if(i == len) len ++;
}
return len;
}
Another improvement is that when the next element to be judged is larger than the last element of res, it does not need to use binary search to put it directly at the end. As follows, the efficiency will be improved.
public static int findPositionToReplace(int[] a, int low, int high, int x) {
int mid;
while (low <= high) {
mid = low + (high - low) / 2;
if (a[mid] == x)
return mid;
else if (a[mid] > x)
high = mid - 1;
else
low = mid + 1;
}
return low;
}
public static int lengthOfLIS1(int[] nums) {
if (nums == null | nums.length == 0)
return 0;
int n = nums.length, len = 0;
int[] increasingSequence = new int[n];
increasingSequence[len++] = nums[0];
for (int i = 1; i < n; i++) {
if (nums[i] > increasingSequence[len - 1])
increasingSequence[len++] = nums[i];
else {
int position = findPositionToReplace(increasingSequence, 0, len - 1, nums[i]);
increasingSequence[position] = nums[i];
}
}
return len;
}
Of course, both of the above schemes are o(nlogn) time complexity, and there is an o(n2) solution, as follows:
public int lengthOfLIS(int[] nums) {
int N = nums.length;
if (N == 0) return 0;
int[] dp = new int[N];
Arrays.fill(dp, 1);
int res = 1;
for (int i = 1; i < N; i++) {
for (int j = 0; j < i; j++) {
if (nums[j] < nums[i]) {
dp[i] = Math.max(dp[j] + 1, dp[i]);
}
}
res = Math.max(res, dp[i]);
}
return res;
}