Given a sequence of integers, find the longest increasing subsequence (LIS).
You code should return the length of the LIS.
Have you met this question in a real interview?
Yes
Clarification
What's the definition of longest increasing subsequence?
The longest increasing subsequence problem is to find a subsequence of a given sequence in which the subsequence's elements are in sorted order, lowest to highest, and in which the subsequence is as long as possible. This subsequence is not necessarily contiguous, or unique.
https://en.wikipedia.org/wiki/Longest_increasing_subsequence
Example
For[5, 4, 1, 2, 3], the LIS is[1, 2, 3], return3
For[4, 2, 4, 5, 3, 7], the LIS is[2, 4, 5, 7], return4
- dp
- binary search
dp f[i] 代表以i结尾的longest increasing subsequence
public class Solution {
/*
* @param nums: An integer array
* @return: The length of LIS (longest increasing subsequence)
*/
//f[n] is the longest increasing subsequence ends with n
//f[n] = max(f[i] i = 0 - (n-1) | nums[i] < nums[n])
//ans = max(f[i], i = 0 - n - 1)
public int longestIncreasingSubsequence(int[] nums) {
// write your code here
if (nums == null || nums.length == 0) {
return 0;
}
int[] f = new int[nums.length];
f[0] = 1;
int max = 0;
for (int i = 1; i < nums.length; i++) {
f[i] = 1;
for (int j = 0; j < i; j++) {
if (nums[j] < nums[i]) {
f[i] = Math.max(f[i], f[j] + 1);
}
}
max = Math.max(f[i], max);
}
return max;
}
}
- binary search
建一个数组存储至当前元素时的最长序列,每遍历到一个新的元素就去最长序列数组中二分查找第一个比这个数相等或大的数并且取代它,最后则会剩下一个答案
public class Solution {
/*
* @param nums: An integer array
* @return: The length of LIS (longest increasing subsequence)
*/
public int longestIncreasingSubsequence(int[] nums) {
// write your code here
if (nums == null || nums.length == 0) {
return 0;
}
int[] maxLast = new int[nums.length + 1];
maxLast[0] = Integer.MIN_VALUE;
for (int i = 1; i <= nums.length; i++) {
maxLast[i] = Integer.MAX_VALUE;
}
for (int i = 0; i < nums.length; i++) {
//find the first num in maxLast that is greater than or equals to
//then replace that digit
int index = binarySearch(maxLast, nums[i]);
maxLast[index] = nums[i];
}
for (int i = nums.length; i > 0; i--) {
if (maxLast[i] != Integer.MAX_VALUE) {
return i;
}
}
return 0;
}
//find the first num in maxLast
public int binarySearch(int[] maxLast, int num) {
int start = 0;
int end = maxLast.length - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (maxLast[mid] < num) {
start = mid;
} else {
end = mid;
}
}
if (maxLast[start] >= num) {
return start;
}
return end;
}
}