📜  正整数和负整数中最长的交替子序列

📅  最后修改于: 2021-05-07 00:14:09             🧑  作者: Mango

仅给出正负数组arr [] 。任务是找到阵列中存在的最长交替(均值为负-正-负或正-负-正-正)子序列的长度。

例子:

方法:
使用动态编程可以解决此问题。它是最长增加子序列(LIS)的一种变体。步骤如下:

  1. 为了在LAS(最长替代子序列)的给定数组arr []中包含和排除元素,使用了变量pos ,当pos = true表示当前元素需要为正,如果pos = false则当前元素需要为负。
  2. 如果我们包含当前元素,请更改pos的值并为下一个元素重复发生,因为我们需要与上一个包含的元素相反符号的下一个元素。
  3. 现在, LAS [i] [pos]可以递归写为:
    • 基本情况:如果递归调用的索引大于最后一个元素,则返回0,因为没有剩下要形成LAS的元素,并且如果计算了LAS [i] [pos] ,则返回该值。
    • 递归调用:如果不满足基本条件,则在包含和排除当前元素时递归调用,然后在那些索引中找到最大值以找到LAS。
    • 返回语句:在每个递归调用中(基本情况除外),返回LAS [i] [pos]的值
  4. 给定数组arr []的LAS是LAS [0] [0]和LAS [0] [1]的最大值。

下面是上述方法的实现:

C++
// C++ program to find the
// length of longest alternate
// subsequence
#include 
using namespace std;
  
// LAS[i][pos] array to find
// the length of LAS till
// index i by including or
// excluding element arr[i]
// on the basis of value of pos
int LAS[1000][2] = { false };
  
int solve(int arr[], int n, int i, bool pos)
{
    // Base Case
    if (i == n)
        return 0;
  
    if (LAS[i][pos])
        return LAS[i][pos];
  
    int inc = 0, exc = 0;
  
    // If current element is
    // positive and pos is true
    // Include the current element
    // and change pos to false
    if (arr[i] > 0 && pos == true) {
        pos = false;
  
        // Recurr for the next
        // iteration
        inc = 1 + solve(arr, n, i + 1, pos);
    }
  
    // If current element is
    // negative and pos is false
    // Include the current element
    // and change pos to true
    else if (arr[i] < 0 && pos == false) {
        pos = true;
  
        // Recurr for the next
        // iteration
        inc = 1 + solve(arr, n, i + 1, pos);
    }
  
    // If current element is
    // excluded, reccur for
    // next iteration
    exc = solve(arr, n, i + 1, pos);
  
    LAS[i][pos] = max(inc, exc);
  
    return LAS[i][pos];
}
  
// Driver's Code
int main()
{
    int arr[] = { -1, 2, 3, 4, 5,
                  -6, 8, -99 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    // Print LAS
    cout << max(solve(arr, n, 0, 0),
                solve(arr, n, 0, 1));
}


Java
// Java program to find the
// length of longest alternate
// subsequence
class GFG {
  
// LAS[i][pos] array to find
// the length of LAS till
// index i by including or
// excluding element arr[i]
// on the basis of value of pos
static int LAS[][] = new int[1000][2];
  
static int solve(int arr[], int n, int i,int pos)
{
      
    // Base Case
    if (i == n)
        return 0;
  
    if (LAS[i][pos]== 1)
        return LAS[i][pos];
  
    int inc = 0, exc = 0;
  
    // If current element is
    // positive and pos is 1
    // Include the current element
    // and change pos to 0
    if (arr[i] > 0 && pos == 1) {
        pos = 0;
  
        // Recurr for the next
        // iteration
        inc = 1 + solve(arr, n, i + 1, pos);
    }
  
    // If current element is
    // negative and pos is o
    // Include the current element
    // and change pos to 1
    else if (arr[i] < 0 && pos == 0) {
        pos = 1;
  
        // Recurr for the next
        // iteration
        inc = 1 + solve(arr, n, i + 1, pos);
    }
  
    // If current element is
    // excluded, reccur for
    // next iteration
    exc = solve(arr, n, i + 1, pos);
  
    LAS[i][pos] = Math.max(inc, exc);
  
    return LAS[i][pos];
}
  
// Driver's Code
public static void main (String[] args) 
{
    int arr[] = { -1, 2, 3, 4, 5, -6, 8, -99 };
    int n = arr.length;
  
    // Print LAS
    System.out.println(Math.max(solve(arr, n, 0, 0),solve(arr, n, 0, 1)));
}
}
  
// This code is contributed by AnkitRai01


Python3
# Python3 program to find the 
# length of longest alternate 
# subsequence 
import numpy as np
  
# LAS[i][pos] array to find 
# the length of LAS till 
# index i by including or 
# excluding element arr[i] 
# on the basis of value of pos 
LAS = np.zeros((1000, 2))
  
for i in range(1000) :
    for j in range(2) :
        LAS[i][j] = False
  
def solve(arr, n, i, pos) :
  
    # Base Case 
    if (i == n) :
        return 0; 
  
    if (LAS[i][pos]) :
        return LAS[i][pos]; 
  
    inc = 0; exc = 0; 
  
    # If current element is 
    # positive and pos is true 
    # Include the current element 
    # and change pos to false 
    if (arr[i] > 0 and pos == True) :
        pos = False; 
  
        # Recurr for the next 
        # iteration 
        inc = 1 + solve(arr, n, i + 1, pos); 
  
    # If current element is 
    # negative and pos is false 
    # Include the current element 
    # and change pos to true 
    elif (arr[i] < 0 and pos == False) :
        pos = True; 
  
        # Recurr for the next 
        # iteration 
        inc = 1 + solve(arr, n, i + 1, pos); 
      
    # If current element is 
    # excluded, reccur for 
    # next iteration 
    exc = solve(arr, n, i + 1, pos); 
  
    LAS[i][pos] = max(inc, exc); 
  
    return LAS[i][pos]; 
  
# Driver's Code 
if __name__ == "__main__" : 
  
    arr = [ -1, 2, 3, 4, 5, -6, 8, -99 ]; 
    n = len(arr); 
  
    # Print LAS 
    print(max(solve(arr, n, 0, 0), solve(arr, n, 0, 1))); 
      
# This code is contributed by AnkitRai01


C#
// C# program to find the
// length of longest alternate
// subsequence
  
using System;
  
public class GFG {
  
// LAS[i][pos] array to find
// the length of LAS till
// index i by including or
// excluding element arr[i]
// on the basis of value of pos
static int [,]LAS = new int[1000,2];
  
static int solve(int []arr, int n, int i,int pos)
{
      
    // Base Case
    if (i == n)
        return 0;
  
    if (LAS[i,pos]== 1)
        return LAS[i,pos];
  
    int inc = 0, exc = 0;
  
    // If current element is
    // positive and pos is 1
    // Include the current element
    // and change pos to 0
    if (arr[i] > 0 && pos == 1) {
        pos = 0;
  
        // Recurr for the next
        // iteration
        inc = 1 + solve(arr, n, i + 1, pos);
    }
  
    // If current element is
    // negative and pos is o
    // Include the current element
    // and change pos to 1
    else if (arr[i] < 0 && pos == 0) {
        pos = 1;
  
        // Recurr for the next
        // iteration
        inc = 1 + solve(arr, n, i + 1, pos);
    }
  
    // If current element is
    // excluded, reccur for
    // next iteration
    exc = solve(arr, n, i + 1, pos);
  
    LAS[i,pos] = Math.Max(inc, exc);
  
    return LAS[i,pos];
}
  
// Driver's Code
public static void Main() 
{
    int []arr = { -1, 2, 3, 4, 5, -6, 8, -99 };
    int n = arr.Length;
  
    // Print LAS
    Console.WriteLine(Math.Max(solve(arr, n, 0, 0),solve(arr, n, 0, 1)));
}
}
  
// This code is contributed by AnkitRai01


输出:
5

时间复杂度: O(N)其中N是数组的长度。