📜  仅允许一次插入操作时的最长连续子序列

📅  最后修改于: 2021-09-22 09:45:36             🧑  作者: Mango

给定一个长度为N的正整数序列。唯一允许的操作是在序列中的任何位置插入具有任何值的单个整数。任务是找到最大长度的子序列,其中包含按递增顺序的连续值。

例子:

方法:想法是使用动态规划。
dp[val][0]是所需子序列的长度,该子序列以等于 val 的元素结束并且该元素尚未插入。令dp[val][1]是所需子序列的长度,该子序列以等于 val 的元素结束并且已经插入了一些元素。
现在将问题分解为子问题如下:
计算dp[val][0],因为没有插入元素,子序列的长度会比之前的值增加1
dp[val][0] = 1 + dp[val – 1][0]

要计算 dp[val][1],请考虑以下两种情况:

  1. 当已经为 (val-1) 插入元素时,从 dp[ val-1 ][ 1 ] 开始,长度会增加 1
  2. 当元素尚未插入时,则可以插入值为 (val-1) 的元素。因此,从 dp[ val-2 ][ 0 ] 开始,长度会增加 2。

取上述两种情况的最大值。
dp[val][1] = max(1 + dp[val – 1][1], 2 + dp[val – 2][0])

下面是上述方法的实现:

C++
// C++ implementation of above approach
#include 
using namespace std;
 
// Function to return the length of longest
// consecuetive subsequence after inserting an element
int LongestConsSeq(int arr[], int N)
{
 
    // Variable to find maximum value of the array
    int maxval = 1;
 
    // Calculating maximum value of the array
    for (int i = 0; i < N; i += 1) {
 
        maxval = max(maxval, arr[i]);
    }
 
    // Declaring the DP table
    int dp[maxval + 1][2] = { 0 };
 
    // Variable to store the maximum length
    int ans = 1;
 
    // Iterating for every value present in the array
    for (int i = 0; i < N; i += 1) {
 
        // Recurrence for dp[val][0]
        dp[arr[i]][0] = (1 + dp[arr[i] - 1][0]);
 
        // No value can be inserted before 1,
        // hence the element value should be
        // greater than 1 for this recurrance relation
        if (arr[i] >= 2)
 
            // Recurrence for dp[val][1]
            dp[arr[i]][1] = max(1 + dp[arr[i] - 1][1],
                                2 + dp[arr[i] - 2][0]);
        else
 
            // Maximum length of consecutive sequence
            // ending at 1 is equal to 1
            dp[arr[i]][1] = 1;
 
        // Update the ans variable with
        // the new maximum length possible
        ans = max(ans, dp[arr[i]][1]);
    }
 
    // Return the ans
    return ans;
}
 
// Driver code
int main()
{
    // Input array
    int arr[] = { 2, 1, 4, 5 };
 
    int N = sizeof(arr) / sizeof(arr[0]);
 
    cout << LongestConsSeq(arr, N);
 
    return 0;
}


Java
// Java implementation of above approach
 
class GFG
{
    // Function to return the length of longest
    // consecuetive subsequence after inserting an element
    static int LongestConsSeq(int [] arr, int N)
    {
     
        // Variable to find maximum value of the array
        int maxval = 1;
     
        // Calculating maximum value of the array
        for (int i = 0; i < N; i += 1)
        {
            maxval = Math. max(maxval, arr[i]);
        }
     
        // Declaring the DP table
        int [][] dp = new int[maxval + 1][2];
     
        // Variable to store the maximum length
        int ans = 1;
     
        // Iterating for every value present in the array
        for (int i = 0; i < N; i += 1)
        {
     
            // Recurrence for dp[val][0]
            dp[arr[i]][0] = (1 + dp[arr[i] - 1][0]);
     
            // No value can be inserted before 1,
            // hence the element value should be
            // greater than 1 for this recurrance relation
            if (arr[i] >= 2)
     
                // Recurrence for dp[val][1]
                dp[arr[i]][1] = Math.max(1 + dp[arr[i] - 1][1],
                                    2 + dp[arr[i] - 2][0]);
            else
     
                // Maximum length of consecutive sequence
                // ending at 1 is equal to 1
                dp[arr[i]][1] = 1;
     
            // Update the ans variable with
            // the new maximum length possible
            ans = Math.max(ans, dp[arr[i]][1]);
        }
     
        // Return the ans
        return ans;
    }
     
    // Driver code
    public static void main (String[] args)
    {
         
        // Input array
        int [] arr = { 2, 1, 4, 5 };
     
        int N = arr.length;
     
        System.out.println(LongestConsSeq(arr, N));
    }
}
 
// This code is contributed by ihritik


Python3
# Python3 implementation of above approach
 
# Function to return the length of longest
# consecuetive subsequence after inserting an element
def LongestConsSeq(arr, N):
 
    # Variable to find maximum value of the array
    maxval = 1
 
    # Calculating maximum value of the array
    for i in range(N):
 
        maxval = max(maxval, arr[i])
     
 
    # Declaring the DP table
    dp=[[ 0 for i in range(2)] for i in range(maxval + 1)]
 
    # Variable to store the maximum length
    ans = 1
 
    # Iterating for every value present in the array
    for i in range(N):
 
        # Recurrence for dp[val][0]
        dp[arr[i]][0] = 1 + dp[arr[i] - 1][0]
 
        # No value can be inserted before 1,
        # hence the element value should be
        # greater than 1 for this recurrance relation
        if (arr[i] >= 2):
 
            # Recurrence for dp[val][1]
            dp[arr[i]][1] = max(1 + dp[arr[i] - 1][1],
                                2 + dp[arr[i] - 2][0])
        else:
 
            # Maximum length of consecutive sequence
            # ending at 1 is equal to 1
            dp[arr[i]][1] = 1
 
        # Update the ans variable with
        # the new maximum length possible
        ans = max(ans, dp[arr[i]][1])
     
 
    # Return the ans
    return ans
 
# Driver code
 
arr=[2, 1, 4, 5]
 
N = len(arr)
 
print(LongestConsSeq(arr, N))
 
# This code is contributed by mohit kumar 29


C#
// C# implementation of above approach
using System;
 
class GFG
{
    // Function to return the length of longest
    // consecuetive subsequence after inserting an element
    static int LongestConsSeq(int [] arr, int N)
    {
     
        // Variable to find maximum value of the array
        int maxval = 1;
     
        // Calculating maximum value of the array
        for (int i = 0; i < N; i += 1)
        {
     
            maxval =Math.Max(maxval, arr[i]);
        }
     
        // Declaring the DP table
        int [ , ] dp = new int[maxval + 1, 2];
     
        // Variable to store the maximum length
        int ans = 1;
     
        // Iterating for every value present in the array
        for (int i = 0; i < N; i += 1)
        {
     
            // Recurrence for dp[val][0]
            dp[arr[i], 0] = (1 + dp[arr[i] - 1, 0]);
     
            // No value can be inserted before 1,
            // hence the element value should be
            // greater than 1 for this recurrance relation
            if (arr[i] >= 2)
     
                // Recurrence for dp[val][1]
                dp[arr[i], 1] = Math.Max(1 + dp[arr[i] - 1, 1],
                                    2 + dp[arr[i] - 2, 0]);
            else
     
                // Maximum length of consecutive sequence
                // ending at 1 is equal to 1
                dp[arr[i], 1] = 1;
     
            // Update the ans variable with
            // the new maximum length possible
            ans = Math.Max(ans, dp[arr[i], 1]);
        }
     
        // Return the ans
        return ans;
    }
     
    // Driver code
    public static void Main ()
    {
         
        // Input array
        int [] arr = new int [] { 2, 1, 4, 5 };
     
        int N = arr.Length;
     
        Console.WriteLine(LongestConsSeq(arr, N));
    }
}
 
// This code is contributed by ihritik


Javascript


输出:
4

时间复杂度: O(N)
空间复杂度: O(MaxValue) 其中 MaxValue 是数组中存在的最大值。

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程