📜  最长严格双调子序列的长度

📅  最后修改于: 2021-10-27 08:46:41             🧑  作者: Mango

给定一个包含 n 个整数的数组 arr[]。问题是找到最长的严格双调子序列的长度。如果一个子序列首先增加然后减少,条件是在增加和减少的部分相邻之间的绝对差仅为1,则称为严格双调。按递增顺序排序的序列被认为是双音,递减部分为空。类似地,降序序列被认为是双音,递增部分为空。
例子:

Input : arr[] = {1, 5, 2, 3, 4, 5, 3, 2}
Output : 6
The Longest Strict Bitonic Subsequence is:
{1, 2, 3, 4, 3, 2}.

Input : arr[] = {1, 2, 5, 3, 6, 7, 4, 6, 5}
Output : 5

方法一:这个问题可以用寻找最长双音子序列的概念来解决。唯一需要保持的条件是相邻点的差值应该只有 1。它的时间复杂度为 O(n 2 )。
方法 2(高效方法):想法是创建两个哈希映射incdcr,其元组的形式为(ele, len) ,其中len表示以 map inc 中的元素ele结尾的最长递增子序列的长度,长度为分别从map dcr中的元素ele开始的最长递减子序列。还创建两个阵列len_inc []len_dcr []其中len_inc [i]表示与元件ARR [i]len_dcr [I]终了的最大增加子序列的长度代表最大的减小子序列的长度开始元件ARR [I ] 。现在,对于每个元素arr[i]我们可以找到值(arr[i]-1)的长度,如果它存在于哈希表inc 中。将此值设为v (最初 v 将为 0) 。现在,以arr[i]结尾的最长递增子序列的长度将是v+1 。更新此长度以及哈希表inc和数组len_inc[]中相应索引i处的元素 arr[i] 。现在,从右到左遍历数组,我们可以类似地填充哈希表dcr和数组len_dcr[]以获得最长递减子序列。最后,对于每个元素 arr[i] 我们计算(len_inc[i] + len_dcr[i] – 1)并返回最大值。
注意:这里增加和减少子序列仅表示相邻元素之间的差异仅为1。

C++
// C++ implementation to find length of longest
// strict bitonic subsequence
#include 
using namespace std;
    
// function to find length of longest
// strict bitonic subsequence
int longLenStrictBitonicSub(int arr[], int n)
{
    // hash table to map the array element with the
    // length of the longest subsequence of which
    // it is a part of and is the last/first element of
    // that subsequence
    unordered_map inc, dcr;
     
    // arrays to store the length of increasing and
    // decreasing subsequences which end at them
    // or start from them 
    int len_inc[n], len_dcr[n];
     
    // to store the length of longest strict
    // bitonic subsequence
    int longLen = 0;
     
    // traverse the array elements
    // from left to right
    for (int i=0; i=0; i--)
    {
        // initialize current length
        // for element arr[i] as 0
        int len = 0;
           
        // if 'arr[i]-1' is in 'dcr'
        if (dcr.find(arr[i]-1) != dcr.end())
            len = dcr[arr[i]-1];
           
        // update arr[i] subsequence length in 'dcr'
        // and in len_dcr[]   
        dcr[arr[i]] = len_dcr[i] = len + 1;
    }
     
    // calculating the length of all the strict
    // bitonic subsequence
    for (int i=0; iJava
// Java implementation to find length of longest
// strict bitonic subsequence
import java.util.*;
 
class GfG
{
     
// function to find length of longest
// strict bitonic subsequence
static int longLenStrictBitonicSub(int arr[], int n)
{
    // hash table to map the array element with the
    // length of the longest subsequence of which
    // it is a part of and is the last/first element of
    // that subsequence
    HashMap inc = new HashMap ();
    HashMap dcr = new HashMap ();
     
    // arrays to store the length of increasing and
    // decreasing subsequences which end at them
    // or start from them
    int len_inc[] = new int[n];
    int len_dcr[] = new int[n];
     
    // to store the length of longest strict
    // bitonic subsequence
    int longLen = 0;
     
    // traverse the array elements
    // from left to right
    for (int i = 0; i < n; i++)
    {
        // initialize current length
        // for element arr[i] as 0
        int len = 0;
             
        // if 'arr[i]-1' is in 'inc'
        if (inc.containsKey(arr[i] - 1))
            len = inc.get(arr[i] - 1);
             
        // update arr[i] subsequence length in 'inc'    
        // and in len_inc[]
        len_inc[i] = len + 1;
        inc.put(arr[i], len_inc[i]);
    }
     
    // traverse the array elements
    // from right to left
    for (int i = n - 1; i >= 0; i--)
    {
        // initialize current length
        // for element arr[i] as 0
        int len = 0;
             
        // if 'arr[i]-1' is in 'dcr'
        if (dcr.containsKey(arr[i] - 1))
            len = dcr.get(arr[i] - 1);
             
        // update arr[i] subsequence length in 'dcr'
        // and in len_dcr[]
        len_dcr[i] = len + 1;
        dcr.put(arr[i], len_dcr[i]);
    }
     
    // calculating the length of all the strict
    // bitonic subsequence
    for (int i = 0; i < n; i++)
        if (longLen < (len_inc[i] + len_dcr[i] - 1))
            longLen = len_inc[i] + len_dcr[i] - 1;
         
    // required longest length strict
    // bitonic subsequence
    return longLen;    
}
     
// Driver code
public static void main(String[] args)
{
    int arr[] = {1, 5, 2, 3, 4, 5, 3, 2};
    int n = arr.length;
    System.out.println("Longest length strict " +
                            "bitonic subsequence = " +
                            longLenStrictBitonicSub(arr, n));
}
}
 
// This code is contributed by
// prerna saini


Python3
# Python3 implementation to find length of
# longest strict bitonic subsequence
 
# function to find length of longest
# strict bitonic subsequence
def longLenStrictBitonicSub(arr, n):
 
    # hash table to map the array element
    # with the length of the longest subsequence
    # of which it is a part of and is the
    # last/first element of that subsequence
    inc, dcr = dict(), dict()
 
    # arrays to store the length of increasing
    # and decreasing subsequences which end at
    # them or start from them
    len_inc, len_dcr = [0] * n, [0] * n
 
    # to store the length of longest strict
    # bitonic subsequence
    longLen = 0
 
    # traverse the array elements
    # from left to right
    for i in range(n):
 
        # initialize current length
        # for element arr[i] as 0
        len = 0
 
        # if 'arr[i]-1' is in 'inc'
        if inc.get(arr[i] - 1) in inc.values():
            len = inc.get(arr[i] - 1)
         
        # update arr[i] subsequence length in 'inc'    
        # and in len_inc[]
        inc[arr[i]] = len_inc[i] = len + 1
     
    # traverse the array elements
    # from right to left
    for i in range(n - 1, -1, -1):
 
        # initialize current length
        # for element arr[i] as 0
        len = 0
 
        # if 'arr[i]-1' is in 'dcr'
        if dcr.get(arr[i] - 1) in dcr.values():
            len = dcr.get(arr[i] - 1)
         
        # update arr[i] subsequence length 
        # in 'dcr' and in len_dcr[]
        dcr[arr[i]] = len_dcr[i] = len + 1
     
    # calculating the length of
    # all the strict bitonic subsequence
    for i in range(n):
        if longLen < (len_inc[i] + len_dcr[i] - 1):
            longLen = len_inc[i] + len_dcr[i] - 1
     
    # required longest length strict
    # bitonic subsequence
    return longLen
 
# Driver Code
if __name__ == "__main__":
    arr = [1, 5, 2, 3, 4, 5, 3, 2]
    n = len(arr)
    print("Longest length strict bitonic subsequence =",
           longLenStrictBitonicSub(arr, n))
 
# This code is contributed by sanjeev2552


C#
// C# implementation to find length of longest
// strict bitonic subsequence
using System;
using System.Collections.Generic;
 
class GfG
{
 
    // function to find length of longest
    // strict bitonic subsequence
    static int longLenStrictBitonicSub(int []arr, int n)
    {
        // hash table to map the array
        // element with the length of
        // the longest subsequence of
        // which it is a part of and
        // is the last/first element of
        // that subsequence
        Dictionary inc = new Dictionary ();
        Dictionary dcr = new Dictionary ();
 
        // arrays to store the length
        // of increasing and decreasing
        // subsequences which end at them
        // or start from them
        int []len_inc = new int[n];
        int []len_dcr = new int[n];
 
        // to store the length of longest strict
        // bitonic subsequence
        int longLen = 0;
 
        // traverse the array elements
        // from left to right
        for (int i = 0; i < n; i++)
        {
            // initialize current length
            // for element arr[i] as 0
            int len = 0;
 
            // if 'arr[i]-1' is in 'inc'
            if (inc.ContainsKey(arr[i] - 1))
                len = inc[arr[i] - 1];
 
            // update arr[i] subsequence length     
            // in 'inc' and in len_inc[]
            len_inc[i] = len + 1;
            if (inc.ContainsKey(arr[i]))
            {
                inc.Remove(arr[i]);
                inc.Add(arr[i], len_inc[i]);
            }
            else
                inc.Add(arr[i], len_inc[i]);
        }
 
        // traverse the array elements
        // from right to left
        for (int i = n - 1; i >= 0; i--)
        {
            // initialize current length
            // for element arr[i] as 0
            int len = 0;
 
            // if 'arr[i]-1' is in 'dcr'
            if (dcr.ContainsKey(arr[i] - 1))
                len = dcr[arr[i] - 1];
 
            // update arr[i] subsequence length in 'dcr'
            // and in len_dcr[]
            len_dcr[i] = len + 1;
            if (dcr.ContainsKey(arr[i]))
            {
                dcr.Remove(arr[i]);
                dcr.Add(arr[i], len_dcr[i]);
            }
            else
                dcr.Add(arr[i], len_dcr[i]);
        }
 
        // calculating the length of all the strict
        // bitonic subsequence
        for (int i = 0; i < n; i++)
            if (longLen < (len_inc[i] + len_dcr[i] - 1))
                longLen = len_inc[i] + len_dcr[i] - 1;
 
        // required longest length strict
        // bitonic subsequence
        return longLen;
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        int []arr = {1, 5, 2, 3, 4, 5, 3, 2};
        int n = arr.Length;
        Console.WriteLine("Longest length strict " +
                            "bitonic subsequence = " +
                            longLenStrictBitonicSub(arr, n));
    }
}
 
// This code is contributed by Rajput-Ji


Javascript


输出:

Longest length strict bitonic subsequence = 6

时间复杂度: O(n)。
辅助空间: O(n)。

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