最长增长子序列(LIS)问题是找到给定序列的最长子序列的长度,以使子序列的所有元素都按升序排序。例如,{10、22、9、33、21、50、41、60、80}的LIS长度为6,LIS为{10、22、33、50、60、80}。
例子:
Input : arr[] = {3, 10, 2, 1, 20}
Output : Length of LIS = 3
The longest increasing subsequence is 3, 10, 20
Input : arr[] = {3, 2}
Output : Length of LIS = 1
The longest increasing subsequences are {3} and {2}
Input : arr[] = {50, 3, 10, 7, 40, 80}
Output : Length of LIS = 4
The longest increasing subsequence is {3, 7, 40, 80}
重叠子问题:
考虑到上述实现,下面是大小为4的数组的递归树。lis(n)给出了arr []的LIS长度。
lis(4)
/ |
lis(3) lis(2) lis(1)
/ /
lis(2) lis(1) lis(1)
/
lis(1)
我们可以看到,有许多子问题一次又一次地得到解决。因此,此问题具有“重叠子结构”属性,可以通过使用“记忆化”或“制表”来避免相同子问题的重新计算。以下是LIS问题的列表实现。
C++
/* Dynamic Programming C/C++ implementation of LIS problem */
#include
#include
/* lis() returns the length of the longest increasing
subsequence in arr[] of size n */
int lis(int arr[], int n)
{
int *lis, i, j, max = 0;
lis = (int*)malloc(sizeof(int) * n);
/* Initialize LIS values for all indexes */
for (i = 0; i < n; i++)
lis[i] = 1;
/* Compute optimized LIS values in bottom up manner */
for (i = 1; i < n; i++)
for (j = 0; j < i; j++)
if (arr[i] > arr[j] && lis[i] < lis[j] + 1)
lis[i] = lis[j] + 1;
/* Pick maximum of all LIS values */
for (i = 0; i < n; i++)
if (max < lis[i])
max = lis[i];
/* Free memory to avoid memory leak */
free(lis);
return max;
}
/* Driver program to test above function */
int main()
{
int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };
int n = sizeof(arr) / sizeof(arr[0]);
printf("Length of lis is %d\n", lis(arr, n));
return 0;
}
Java
/* Dynamic Programming Java implementation
of LIS problem */
import java.util.*;
class GFG
{
/*
* lis() returns the length of the longest
* increasing subsequence in arr[] of size n
*/
static int lis(int[] arr, int n)
{
int max = 0;
int[] lst = new int[n];
// initialize LIS values for all indexes
Arrays.fill(lst, 1);
/* Compute optimized LIS values
in bottom up manner */
for (int i = 1; i < n; i++)
{
for (int j = 0; j < i; j++)
{
if (arr[i] > arr[j] &&
lst[i] < lst[j] + 1)
lst[i] = lst[j] + 1;
}
}
/* Pick maximum of all LIS values */
for (int i = 0; i < n; i++)
if (max < lst[i])
max = lst[i];
return max;
}
// Driver Code
public static void main(String[] args)
{
int[] arr = { 10, 22, 9, 33, 21, 50, 41, 60 };
int n = arr.length;
System.out.println("Length of lis is " +
lis(arr, n));
}
}
// This code is contributed by
// sanjeev2552
Python3
# Dyanmic Programming python3
# implementation of LIS problem
# lis() returns the length of the
# longest increasing subsequence
# in arr[] of size n
def lis(arr, n):
i, j, maxm = 0, 0, 0
# initialize LIS values for all indexes
lst = [1 for s in range(n)]
for i in range(1, n):
for j in range(0, i):
if (arr[i] > arr[j] and
lst[i] < lst[j] + 1):
lst[i] = lst[j] + 1
# Pick maximum of all LIS values
for i in range(0, n):
if maxm < lst[i]:
maxm = lst[i]
return maxm
# Driver Code
arr = [10, 22, 9, 33, 21, 50, 41, 60]
n = len(arr)
print("Length of lst is", lis(arr, n))
# This code is contributed
# by Mohit kumar 29
C#
/* Dynamic Programming Java implementation
of LIS problem */
using System;
public class GFG
{
/*
* lis() returns the length of the longest
* increasing subsequence in arr[] of size n
*/
static int lis(int[] arr, int n)
{
int max = 0;
int[] lst = new int[n];
// initialize LIS values for all indexes
Array.Fill(lst, 1);
/* Compute optimized LIS values
in bottom up manner */
for (int i = 1; i < n; i++)
{
for (int j = 0; j < i; j++)
{
if (arr[i] > arr[j] && lst[i] < lst[j] + 1)
{
lst[i] = lst[j] + 1;
}
}
}
/* Pick maximum of all LIS values */
for (int i = 0; i < n; i++)
if (max < lst[i])
max = lst[i];
return max;
}
// Driver code
static public void Main ()
{
int[] arr = { 10, 22, 9, 33, 21, 50, 41, 60 };
int n = arr.Length;
Console.WriteLine("Length of lis is " + lis(arr, n));
}
}
// This code is contributed by avanitrachhadiya2155
输出:
Length of lis is 5
请参考有关动态编程的完整文章。设置3(最长递增子序列)以获取更多详细信息!
想要从精选的最佳视频中学习并解决问题,请查看有关从基础到高级C++的C++基础课程以及有关语言和STL的C++ STL课程。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程” 。