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

📅  最后修改于: 2021-05-06 22:03:54             🧑  作者: 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


输出:
4

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