Longest alternating subsequence in terms of positive and negative integers - GeeksforGeeks

31 May, 2021
Given an array arr[] of positive and negative numbers only. The task is to find the length of the longest alternating (means negative-positive-negative or positive-negative-positive) subsequence present in the array. 
Examples: 
Input: arr[] = {-4, 3, -5, 9, 10, 12, 2, -1} Output: 5 Explanation: The longest sequence is {-4, 3, -5, 9, -1}, which is of length 5. There can be many more subsequences of this length.
Input: arr[] = {10, 12, 2, -1} Output: 2 Explanation: The longest sequence is {10, -1}, which is 2. There can be many more subsequences of this length. 
Approach: This problem can be solved using Dynamic Programming. It is a variation Longest Increasing Subsequence(LIS). The following are the steps: 
For including and excluding an element in the given array arr[] for LAS(Longest Alternative Subsequence), a variable pos is used, when pos = true means the current element needs to be positive and if pos = false then current element needs to be negative.If we include the current element, change the value of pos and recurr for the next element because we need the next element of the opposite to the previously included element.Now LAS[i][pos] can be recursively written as: Base case: If the index called recursively is greater than the last element, then return 0, as there is no such element left to form LAS and if LAS[i][pos] is calculated, then return the value. 
For including and excluding an element in the given array arr[] for LAS(Longest Alternative Subsequence), a variable pos is used, when pos = true means the current element needs to be positive and if pos = false then current element needs to be negative.
If we include the current element, change the value of pos and recurr for the next element because we need the next element of the opposite to the previously included element.
Now LAS[i][pos] can be recursively written as: Base case: If the index called recursively is greater than the last element, then return 0, as there is no such element left to form LAS and if LAS[i][pos] is calculated, then return the value. 
Base case: If the index called recursively is greater than the last element, then return 0, as there is no such element left to form LAS and if LAS[i][pos] is calculated, then return the value. 
if(i == N) { return 0; } if(LAS[i][pos]) { return LAS[i][pos]; } 
Recursive call: If the base case is not met, then recursively call when current element is included and excluded, then find the maximum of those to find LAS at that index.  
LAS[i][pos] = Longest Alternating Subsequence at index i by including or excluding that element for the value of pos, LAS[i][pos] = max(1 + recursive_function(i+1, pos), recursive_function(i+1, pos));  
Return statement: At each recursive call(except the base case), return the value of LAS[i][pos].  
return LAS[i][pos];  
The LAS for the given array arr[] is the maximum of LAS[0][0] and LAS[0][1].
The LAS for the given array arr[] is the maximum of LAS[0][0] and LAS[0][1].
Below is the implementation of the above approach: 
C++
Java
Python3
C#
Javascript
// C++ program to find the// length of longest alternate// subsequence#include <bits/stdc++.h>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 posint 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 Codeint 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 program to find the// length of longest alternate// subsequenceclass 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 posstatic 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 Codepublic 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 program to find the# length of longest alternate# subsequenceimport 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 posLAS = 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 Codeif __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# 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 posstatic 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 Codepublic 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
<script>// Javascript program to find the// length of longest alternate// subsequence  // 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 poslet LAS = new Array(); for(let i = 0; i < 1000; i++){    let temp = new Array()    for(let j = 0; j < 2; j++){        temp.push([])    }    LAS.push(temp);} for(let i = 0; i < 1000; i++){    for(let j = 0; j < 2; j++){        LAS[i][j] = false    }} function solve(arr, n, i, pos){    // Base Case    if (i == n)        return 0;     if (LAS[i][pos])        return LAS[i][pos];     let 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] = Math.max(inc, exc);     return LAS[i][pos];} // Driver's Code let arr = [ -1, 2, 3, 4, 5,            -6, 8, -99 ];let n = arr.length; // Print LASdocument.write(Math.max(solve(arr, n, 0, 0), solve(arr, n, 0, 1))); // This code is contributed by _saurabh_jaiswal</script>
5
 
Time Complexity: O(N) where N is the length of the array. 
ankthon
_saurabh_jaiswal
Arrays
Dynamic Programming
Recursion
Arrays
Dynamic Programming
Recursion
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Stack Data Structure (Introduction and Program)
Top 50 Array Coding Problems for Interviews
Introduction to Arrays
Multidimensional Arrays in Java
Linear Search
0-1 Knapsack Problem | DP-10
Longest Common Subsequence | DP-4
Longest Increasing Subsequence | DP-3
Bellman–Ford Algorithm | DP-23
Floyd Warshall Algorithm | DP-16