[Algorithms] Longest Increasing Subsequence

简介: The Longest Increasing Subsequence (LIS) problem requires us to find a subsequence t of a given sequence s, such that t satisfies two requirements: ...

The Longest Increasing Subsequence (LIS) problem requires us to find a subsequence t of a given sequence s, such that t satisfies two requirements:

  1. Elements in t are sorted in ascending order;
  2. t is as long as possible.

This problem can be solved using Dynamic Programming. We define the state P[i] to be the length of the longest increasing subsequence ends at i (with s[i] as its last element). Then the state equations are:

  1. P[i] = max_{j = 0, ..., i - 1 and arr[j] < arr[i]} P[j] + 1;
  2. If no such j exists, P[i] = 1.

Putting these into code using a table to store results for smaller problems and solve it in a bottom-up manner. We will have the following code.

 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 
 5 using namespace std;
 6 
 7 int longestIncreasingSubsequence(vector<int>& nums) {
 8     vector<int> dp(nums.size(), 1);
 9     int maxlen = 0;
10     for (int i = 1; i < nums.size(); i++) {
11         for (int j = 0; j < i; j++) {
12             if (nums[j] < nums[i] && dp[j] + 1 > dp[i]) {
13                 dp[i] = dp[j] + 1;
14                 maxlen = max(maxlen, dp[i]);
15             }
16         }
17     }
18     return maxlen;
19 }
20 
21 void longestIncreasingSubsequenceTest(void) {
22     int num[] = {10, 22, 9, 33, 21, 50, 41, 60, 80};
23     vector<int> nums(num, num + sizeof(num) / sizeof(int));
24     printf("%d\n", longestIncreasingSubsequence(nums));
25 }
26 
27 int main(void) {
28     longestIncreasingSubsequenceTest();
29     system("pause");
30     return 0;
31 }

 This program only computes the length of the LIS. If you want to print all the possible LIS, you need to modify the above program. Specifically, you may want to use backtracking to obtain all the possible LIS. My code is as follows. Welcome for any comments. Thank you!

 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 
 5 using namespace std;
 6 
 7 /* Helper function to find all LCS. */
 8 void findAllLCSHelper(vector<int>& nums, vector<int>& dp, vector<int>& seq, vector<vector<int> >& res, int maxlen, int end) {
 9     if (maxlen == 0) {
10         reverse(seq.begin(), seq.end());
11         res.push_back(seq);
12         reverse(seq.begin(), seq.end());
13         return;
14     }
15     for (int i = end; i >= 0; i--) {
16         if (dp[i] == maxlen && (seq.empty() || nums[i] < seq.back())) {
17             seq.push_back(nums[i]);
18             findAllLCSHelper(nums, dp, seq, res, maxlen - 1, i - 1);
19             seq.pop_back();
20         }
21     }
22 }
23 
24 /* Function to find all LCS. */
25 vector<vector<int> > findAllLCS(vector<int>& nums, vector<int>& dp, int maxlen) {
26     vector<vector<int> > res;
27     vector<int> seq;
28     findAllLCSHelper(nums, dp, seq, res, maxlen, nums.size() - 1);
29     return res;
30 }
31 
32 /* Compute the length of LCS and print all of them. */
33 int longestIncreasingSubsequence(vector<int>& nums) {
34     vector<int> dp(nums.size(), 1);
35     int maxlen = 0;
36     for (int i = 1; i < (int)nums.size(); i++) {
37         for (int j = 0; j < i; j++) {
38             if (nums[j] < nums[i] && dp[j] + 1 > dp[i]) {
39                 dp[i] = dp[j] + 1;
40                 maxlen = max(maxlen, dp[i]);
41             }
42         }
43     }
44     vector<vector<int> > lcss = findAllLCS(nums, dp, maxlen);
45     for (int i = 0; i < (int)lcss.size(); i++) {
46         for (int j = 0; j < (int)lcss[i].size(); j++)
47             printf("%d ", lcss[i][j]);
48         printf("\n");
49     }
50     return maxlen;
51 }
52 
53 /* Test function. */
54 void longestIncreasingSubsequenceTest(void) {
55     int num[] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15};
56     vector<int> nums(num, num + sizeof(num) / sizeof(int));
57     printf("%d\n", longestIncreasingSubsequence(nums));
58 }
59 
60 int main(void) {
61     longestIncreasingSubsequenceTest();
62     system("pause");
63     return 0;
64 }

Running this program in Microsoft Visual Professional 2012 gives the following results.

0 2 6 9 11 15
0 4 6 9 11 15
0 2 6 9 13 15
0 4 6 9 13 15
6

The first four rows are the four LIS.

目录
相关文章
|
1月前
|
算法
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
这篇文章介绍了动态规划算法中解决最大上升子序列问题(LIS)的方法,包括问题的描述、动态规划的步骤、状态表示、递推方程、计算最优值以及优化方法,如非动态规划的二分法。
66 0
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
|
算法
LeetCode 300. Longest Increasing Subsequence
给定一个无序的整数数组,找到其中最长上升子序列的长度。
54 0
LeetCode 300. Longest Increasing Subsequence
|
算法
LeetCode 334. Increasing Triplet Subsequence
给定一个未排序的数组,判断这个数组中是否存在长度为 3 的递增子序列。 数学表达式如下: 如果存在这样的 i, j, k, 且满足 0 ≤ i < j < k ≤ n-1, 使得 arr[i] < arr[j] < arr[k] ,返回 true ; 否则返回 false 。
92 0
LeetCode 334. Increasing Triplet Subsequence
|
算法
LeetCode 128. Longest Consecutive Sequence
给定一个未排序的整数数组,找出最长连续序列的长度。 要求算法的时间复杂度为 O(n)。
88 0
LeetCode 128. Longest Consecutive Sequence
|
存储
LeetCode 329. Longest Increasing Path in a Matrix
给定一个整数矩阵,找出最长递增路径的长度。 对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外(即不允许环绕)。
72 0
LeetCode 329. Longest Increasing Path in a Matrix
【LeetCode】Increasing Triplet Subsequence(334)
  Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the array.
102 0
|
算法 C#
算法题丨Longest Consecutive Sequence
描述 Given an unsorted array of integers, find the length of the longest consecutive elements sequence.
1117 0
1142. Maximal Clique (25) 19‘
#include #include #include #include #include using namespace std; int e[201][201]; vector temp; bool judge(){ int flag = 1; for(int i = 0; i < temp.
978 0