Longest alternating subsequence in terms of positive and negative integers

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 recur 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.
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].
Below is the implementation of the above approach:
C++
// 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; // Recur 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; // Recur for the next // iteration inc = 1 + solve(arr, n, i + 1, pos); } // If current element is // excluded, recur 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
// 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; // Recur 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; // Recur for the next // iteration inc = 1 + solve(arr, n, i + 1, pos); } // If current element is // excluded, recur 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
# 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] = Falsedef 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; # Recur 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; # Recur for the next # iteration inc = 1 + solve(arr, n, i + 1, pos); # If current element is # excluded, recur 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// subsequenceusing 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; // Recur 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; // Recur for the next // iteration inc = 1 + solve(arr, n, i + 1, pos); } // If current element is // excluded, recur 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 |
Javascript
<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; // Recur 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; // Recur for the next // iteration inc = 1 + solve(arr, n, i + 1, pos); } // If current element is // excluded, recur for // next iteration exc = solve(arr, n, i + 1, pos); LAS[i][pos] = Math.max(inc, exc); return LAS[i][pos];}// Driver's Codelet 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.
Auxiliary Space: O(n) for call stack
Another approach : Using DP Tabulation method ( Iterative approach )
In this approach we use DP to store computation of subproblems and get the desired output without the help of recursion.
Implementation steps:
- Create a 2D array LAS of size n x 2 to store the lengths of the longest alternating subsequences that end at each index in the array.
- Initialize LAS[0][0] and LAS[0][1] to 1, as the longest alternating subsequence ending at the first index is always of length 1.
- For each pair of indices, check if the subsequence ending at index i can be extended by adding the element at index j. If arr[i] is positive and arr[j] is negative, and if LAS[i][0] < LAS[j][1] + 1, update LAS[i][0] to LAS[j][1] + 1, since adding the element at index j to the subsequence ending at index j will result in a longer alternating subsequence ending at index i
- Similarly, if arr[i] is negative and arr[j] is positive, and if LAS[i][1] < LAS[j][0] + 1, update LAS[i][1] to LAS[j][0] + 1
- Once all possible pairs of indices have been considered, return the maximum value of LAS[n-1][0] and LAS[n-1][1], which represent the lengths of the longest alternating subsequences ending at the last index of the array.
Implementation:
C++
#include <bits/stdc++.h>using namespace std;int solve(int arr[], int n) { // Create a 2D array to store the length of the longest alternating subsequence ending at each index. // The first column stores the length of the longest alternating subsequence ending with a negative number. // The second column stores the length of the longest alternating subsequence ending with a positive number. int LAS[n][2]; // Initialize the first row of LAS to 1 since the subsequence containing only the first element has length 1. LAS[0][0] = LAS[0][1] = 1; // Iterate over the array and fill in the LAS array. for (int i = 1; i < n; i++) { // Initialize the current row to 1 since the subsequence containing only the current element has length 1. LAS[i][0] = LAS[i][1] = 1; // Iterate over the previous elements in the array and update the LAS array. for (int j = 0; j < i; j++) { // If the current element is positive and the previous element is negative, // update the length of the longest alternating subsequence ending with a negative number. if (arr[i] > 0 && arr[j] < 0 && LAS[i][0] < LAS[j][1] + 1) { LAS[i][0] = LAS[j][1] + 1; } // If the current element is negative and the previous element is positive, // update the length of the longest alternating subsequence ending with a positive number. else if (arr[i] < 0 && arr[j] > 0 && LAS[i][1] < LAS[j][0] + 1) { LAS[i][1] = LAS[j][0] + 1; } } } // Return the maximum length of the longest alternating subsequence ending with a negative or positive number. return max(LAS[n-1][0], LAS[n-1][1]);}// Driver's Codeint main() { int arr[] = { -1, 2, 3, 4, 5, -6, 8, -99 }; int n = sizeof(arr) / sizeof(arr[0]); // Print the length of the longest alternating subsequence. cout << solve(arr, n);} |
Java
public class LongestAlternatingSubsequence { public static int solve(int[] arr, int n) { // Create a 2D array to store the length of the longest alternating subsequence. // The first column stores the length of the longest // alternating subsequence ending with a negative number. // The second column stores the length of the longest // alternating subsequence ending with a positive number. int[][] LAS = new int[n][2]; // Initialize the first row of LAS to 1 since the subsequence // containing only the first element has length 1. LAS[0][0] = LAS[0][1] = 1; // Iterate over the array and fill in the LAS array. for (int i = 1; i < n; i++) { // Initialize the current row to 1 since the subsequence // containing only the current element has length 1. LAS[i][0] = LAS[i][1] = 1; // Iterate over the previous elements in the array and update the LAS array. for (int j = 0; j < i; j++) { // If the current element is positive and the previous element is negative, // update the length of the longest alternating subsequence // ending with a negative number. if (arr[i] > 0 && arr[j] < 0 && LAS[i][0] < LAS[j][1] + 1) { LAS[i][0] = LAS[j][1] + 1; } // If the current element is negative and the previous element is positive, // update the length of the longest alternating subsequence ending // with a positive number. else if (arr[i] < 0 && arr[j] > 0 && LAS[i][1] < LAS[j][0] + 1) { LAS[i][1] = LAS[j][0] + 1; } } } // Return the maximum length of the longest alternating // subsequence ending with a negative or positive number. return Math.max(LAS[n - 1][0], LAS[n - 1][1]); } public static void main(String[] args) { int[] arr = { -1, 2, 3, 4, 5, -6, 8, -99 }; int n = arr.length; // Print the length of the longest alternating subsequence. System.out.println(solve(arr, n)); }} |
Python3
# codedef solve(arr, n): # Create a 2D array to store the length of the longest alternating subsequence ending at each index. # The first column stores the length of the longest alternating subsequence ending with a negative number. # The second column stores the length of the longest alternating subsequence ending with a positive number. LAS = [[1, 1] for i in range(n)] # Iterate over the array and fill in the LAS array. for i in range(1, n): # Iterate over the previous elements in the array and update the LAS array. for j in range(i): # If the current element is positive and the previous element is negative, # update the length of the longest alternating subsequence ending with a negative number. if arr[i] > 0 and arr[j] < 0 and LAS[i][0] < LAS[j][1] + 1: LAS[i][0] = LAS[j][1] + 1 # If the current element is negative and the previous element is positive, # update the length of the longest alternating subsequence ending with a positive number. elif arr[i] < 0 and arr[j] > 0 and LAS[i][1] < LAS[j][0] + 1: LAS[i][1] = LAS[j][0] + 1 # Return the maximum length of the longest alternating subsequence ending with a negative or positive number. return max(LAS[n-1][0], LAS[n-1][1])# Driver's Codearr = [-1, 2, 3, 4, 5, -6, 8, -99]n = len(arr)# Print the length of the longest alternating subsequence.print(solve(arr, n)) |
C#
using System;class Program { static int Solve(int[] arr, int n) { // Create a 2D array to store the length of the // longest alternating subsequence ending at each // index. The first column stores the length of the // longest alternating subsequence ending with a // negative number. The second column stores the // length of the longest alternating subsequence // ending with a positive number. int[, ] LAS = new int[n, 2]; // Initialize the first row of LAS to 1 since the // subsequence containing only the first element has // length 1. LAS[0, 0] = LAS[0, 1] = 1; // Iterate over the array and fill in the LAS array. for (int i = 1; i < n; i++) { // Initialize the current row to 1 since the // subsequence containing only the current // element has length 1. LAS[i, 0] = LAS[i, 1] = 1; // Iterate over the previous elements in the // array and update the LAS array. for (int j = 0; j < i; j++) { // If the current element is positive and // the previous element is negative, update // the length of the longest alternating // subsequence ending with a negative // number. if (arr[i] > 0 && arr[j] < 0 && LAS[i, 0] < LAS[j, 1] + 1) { LAS[i, 0] = LAS[j, 1] + 1; } // If the current element is negative and // the previous element is positive, update // the length of the longest alternating // subsequence ending with a positive // number. else if (arr[i] < 0 && arr[j] > 0 && LAS[i, 1] < LAS[j, 0] + 1) { LAS[i, 1] = LAS[j, 0] + 1; } } } // Return the maximum length of the longest // alternating subsequence ending with a negative or // positive number. return Math.Max(LAS[n - 1, 0], LAS[n - 1, 1]); } static void Main() { int[] arr = { -1, 2, 3, 4, 5, -6, 8, -99 }; int n = arr.Length; // Print the length of the longest alternating // subsequence. Console.WriteLine(Solve(arr, n)); }}// This code is contributed by sarojmcy2e |
Javascript
function solve(arr) { let n = arr.length; // Create a 2D array to store the length of the longest alternating subsequence ending at each index. // The first column stores the length of the longest alternating subsequence ending with a negative number. // The second column stores the length of the longest alternating subsequence ending with a positive number. let LAS = Array.from(Array(n), () => new Array(2)); // Initialize the first row of LAS to 1 since the subsequence containing only the first element has length 1. LAS[0][0] = LAS[0][1] = 1; // Iterate over the array and fill in the LAS array. for (let i = 1; i < n; i++) { // Initialize the current row to 1 since the subsequence containing only the current element has length 1. LAS[i][0] = LAS[i][1] = 1; // Iterate over the previous elements in the array and update the LAS array. for (let j = 0; j < i; j++) { // If the current element is positive and the previous element is negative, // update the length of the longest alternating subsequence ending with a negative number. if (arr[i] > 0 && arr[j] < 0 && LAS[i][0] < LAS[j][1] + 1) { LAS[i][0] = LAS[j][1] + 1; } // If the current element is negative and the previous element is positive, // update the length of the longest alternating subsequence ending with a positive number. else if (arr[i] < 0 && arr[j] > 0 && LAS[i][1] < LAS[j][0] + 1) { LAS[i][1] = LAS[j][0] + 1; } } } // Return the maximum length of the longest alternating subsequence ending with a negative or positive number. return Math.max(LAS[n-1][0], LAS[n-1][1]);}let arr = [-1, 2, 3, 4, 5, -6, 8, -99];console.log(solve(arr)); |
Output:
5
Time Complexity: O(N*N)
Auxiliary Space: O(N*N)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



