📜  以正整数和负整数表示的最长交替子序列

📅  最后修改于: 2021-09-17 07:17:11             🧑  作者: Mango

给定一个仅包含正数和负数的数组arr[] 。任务是找到数组中存在的最长交替(意味着负-正-负或正-负-正)子序列的长度。

例子:

方法:
这个问题可以用动态规划解决。它是最长递增子序列(LIS)的变体。以下是步骤:

  1. 为了在给定数组arr[] 中包含和排除 LAS(最长替代子序列)中的元素,使用变量pos ,当pos = true 表示当前元素需要为正时,如果pos = false 则当前元素需要为消极的。
  2. 如果我们包含当前元素,则为下一个元素更改pos和 recurr 的值,因为我们需要与先前包含的元素相反的下一个元素。
  3. 现在LAS[i][pos]可以递归地写为:
    • 基本情况:如果递归调用的索引大于最后一个元素,则返回 0,因为没有这样的元素可以形成 LAS,如果计算LAS[i][pos] ,则返回值。
  • 递归调用:如果不满足基本情况,则在包含和排除当前元素时递归调用,然后找到在该索引处找到 LAS 的最大值。
  • 返回语句:在每次递归调用时(基本情况除外),返回LAS[i][pos] 的值
  1. 给定数组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


Javascript


输出:
5

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

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