Saturday, November 16, 2024
Google search engine
HomeData Modelling & AILongest alternating subsequence in terms of positive and negative integers

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:
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:
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: 

  1. 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.
  2. 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.
  3. 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];  

  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++




// 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 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;
 
        // 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 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;
 
        // 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 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;
 
        # 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
// 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;
 
        // 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 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




<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 pos
let 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 Code
 
let arr = [ -1, 2, 3, 4, 5,
            -6, 8, -99 ];
let n = arr.length;
 
// Print LAS
document.write(Math.max(solve(arr, n, 0, 0), solve(arr, n, 0, 1)));
 
// This code is contributed by _saurabh_jaiswal
</script>


Output

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 Code
int 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




# code
def 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 Code
arr = [-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)

 

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Recent Comments