-
Notifications
You must be signed in to change notification settings - Fork 88
/
LongestIncreasingSubsequence300.java
106 lines (96 loc) · 3.08 KB
/
LongestIncreasingSubsequence300.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/**
* 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?
*/
public class LongestIncreasingSubsequence300 {
public int lengthOfLIS(int[] nums) {
if (nums == null || nums.length == 0) return 0;
int N = nums.length;
int[] dp = new int[N + 1];
int res = 0;
for (int i=1; i<=N; i++) {
dp[i] = 1;
for (int j=1; j<i; j++) {
if (nums[i-1] > nums[j-1]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
if (dp[i] > res) res = dp[i];
}
return res;
}
/**
* https://leetcode.com/problems/longest-increasing-subsequence/solution/
* https://www.geeksforgeeks.org/longest-monotonically-increasing-subsequence-size-n-log-n/
*/
public int lengthOfLIS2(int[] nums) {
int[] dp = new int[nums.length];
int len = 0;
for (int num : nums) {
int i = Arrays.binarySearch(dp, 0, len, num);
if (i < 0) {
i = -(i + 1);
}
dp[i] = num;
if (i == len) {
len++;
}
}
return len;
}
/**
* https://leetcode.com/problems/longest-increasing-subsequence/solution/
*/
public int lengthOfLIS3(int[] nums) {
int memo[][] = new int[nums.length + 1][nums.length];
for (int[] l : memo) {
Arrays.fill(l, -1);
}
return lengthofLIS(nums, -1, 0, memo);
}
public int lengthofLIS(int[] nums, int previndex, int curpos, int[][] memo) {
if (curpos == nums.length) {
return 0;
}
if (memo[previndex + 1][curpos] >= 0) {
return memo[previndex + 1][curpos];
}
int taken = 0;
if (previndex < 0 || nums[curpos] > nums[previndex]) {
taken = 1 + lengthofLIS(nums, curpos, curpos + 1, memo);
}
int nottaken = lengthofLIS(nums, previndex, curpos + 1, memo);
memo[previndex + 1][curpos] = Math.max(taken, nottaken);
return memo[previndex + 1][curpos];
}
/**
* https://leetcode.com/problems/longest-increasing-subsequence/discuss/74824/JavaPython-Binary-search-O(nlogn)-time-with-explanation
*/
public int lengthOfLIS4(int[] nums) {
int[] tails = new int[nums.length];
int size = 0;
for (int x : nums) {
int i = 0, j = size;
while (i != j) {
int m = (i + j) / 2;
if (tails[m] < x)
i = m + 1;
else
j = m;
}
tails[i] = x;
if (i == size) ++size;
}
return size;
}
}