📜  最长递增子序列的 C++ 程序

📅  最后修改于: 2021-09-17 06:42:24             🧑  作者: Mango

最长递增子序列 (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)

我们可以看到有很多子问题被一次又一次地解决了。所以这个问题具有重叠子结构的性质,并且可以通过使用 Memoization 或 Tabulation 来避免相同子问题的重新计算。以下是 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


Javascript


C++
#include 
using namespace std;
int longest_increasing_subsequence(vector& arr)
{
    vector ans;
    int n = arr.size();
    for (int i = 0; i < n; i++) {
        auto it
            = lower_bound(ans.begin(), ans.end(), arr[i]);
        if (it == ans.end()) {
            ans.push_back(arr[i]);
        }
        else {
            *it = arr[i];
        }
    }
    return ans.size();
}
int main()
{
    vector a = { 10, 22, 9, 33, 21, 50, 41, 60 };
    int ans = longest_increasing_subsequence(a);
    cout << ans;
    return 0;
}


输出:
Length of lis is 5

请参阅关于动态规划的完整文章 |设置 3(最长递增子序列)了解更多详情!

方法 2:基于下限的方法

算法 :

1. 迭代数组。

2. 声明一个新数组ans来添加新构造的递增子序列。

2. 对于每个索引,如果lower_bound 指向数组ans的结尾,则将其推入向量ans 中

3. 返回ans数组大小。

C++

#include 
using namespace std;
int longest_increasing_subsequence(vector& arr)
{
    vector ans;
    int n = arr.size();
    for (int i = 0; i < n; i++) {
        auto it
            = lower_bound(ans.begin(), ans.end(), arr[i]);
        if (it == ans.end()) {
            ans.push_back(arr[i]);
        }
        else {
            *it = arr[i];
        }
    }
    return ans.size();
}
int main()
{
    vector a = { 10, 22, 9, 33, 21, 50, 41, 60 };
    int ans = longest_increasing_subsequence(a);
    cout << ans;
    return 0;
}
输出
5
想要从精选的视频和练习题中学习,请查看C++ 基础课程,从基础到高级 C++ 和C++ STL 课程,了解语言和 STL。要完成从学习语言到 DS Algo 等的准备工作,请参阅完整的面试准备课程