Longest alternating subsequence
Last Updated :
21 Dec, 2022
A sequence {X1, X2, .. Xn} is an alternating sequence if its elements satisfy one of the following relations :
X1 < X2 > X3 < X4 > X5 < …. xn or
X1 > X2 < X3 > X4 < X5 > …. xn
Examples:
Input: arr[] = {1, 5, 4}
Output: 3
Explanation: The whole arrays is of the form x1 < x2 > x3
Input: arr[] = {10, 22, 9, 33, 49, 50, 31, 60}
Output: 6
Explanation: The subsequences {10, 22, 9, 33, 31, 60} or
{10, 22, 9, 49, 31, 60} or {10, 22, 9, 50, 31, 60}
are longest subsequence of length 6
Note: This problem is an extension of the longest increasing subsequence problem, but requires more thinking for finding optimal substructure property in this
Longest alternating subsequence using dynamic programming:
To solve the problem follow the below idea:
We will solve this problem by dynamic Programming method, as it has optimal substructure and overlapping subproblems
Follow the below steps to solve the problem:
- Let A is given an array of length N
- We define a 2D array las[n][2] such that las[i][0] contains the longest alternating subsequence ending at index i and the last element is greater than its previous element
- las[i][1] contains the longest alternating subsequence ending at index i and the last element is smaller than its previous element, then we have the following recurrence relation between them,
las[i][0] = Length of the longest alternating subsequence
ending at index i and last element is greater
than its previous element
las[i][1] = Length of the longest alternating subsequence
ending at index i and last element is smaller
than its previous element
Recursive Formulation:
las[i][0] = max (las[i][0], las[j][1] + 1);
for all j < i and A[j] < A[i]
las[i][1] = max (las[i][1], las[j][0] + 1);
for all j < i and A[j] > A[i]
- The first recurrence relation is based on the fact that, If we are at position i and this element has to be bigger than its previous element then for this sequence (upto i) to be bigger we will try to choose an element j ( < i) such that A[j] < A[i] i.e. A[j] can become A[i]’s previous element and las[j][1] + 1 is bigger than las[i][0] then we will update las[i][0].
- Remember we have chosen las[j][1] + 1 not las[j][0] + 1 to satisfy the alternate property because in las[j][0] the last element is bigger than its previous one and A[i] is greater than A[j] which will break the alternating property if we update. So above fact derives the first recurrence relation, a similar argument can be made for the second recurrence relation also.
Below is the implementation of the above approach:
C++
// C++ program to find longest alternating
// subsequence in an array
#include <bits/stdc++.h>
using namespace std;
// Function to return max of two numbers
int max(int a, int b) { return (a > b) ? a : b; }
// Function to return longest alternating
// subsequence length
int zzis(int arr[], int n)
{
/*las[i][0] = Length of the longest
alternating subsequence ending at
index i and last element is greater
than its previous element
las[i][1] = Length of the longest
alternating subsequence ending
at index i and last element is
smaller than its previous element */
int las[n][2];
// Initialize all values from 1
for (int i = 0; i < n; i++)
las[i][0] = las[i][1] = 1;
// Initialize result
int res = 1;
// Compute values in bottom up manner
for (int i = 1; i < n; i++) {
// Consider all elements as
// previous of arr[i]
for (int j = 0; j < i; j++) {
// If arr[i] is greater, then
// check with las[j][1]
if (arr[j] < arr[i]
&& las[i][0] < las[j][1] + 1)
las[i][0] = las[j][1] + 1;
// If arr[i] is smaller, then
// check with las[j][0]
if (arr[j] > arr[i]
&& las[i][1] < las[j][0] + 1)
las[i][1] = las[j][0] + 1;
}
// Pick maximum of both values at index i
if (res < max(las[i][0], las[i][1]))
res = max(las[i][0], las[i][1]);
}
return res;
}
// Driver code
int main()
{
int arr[] = { 10, 22, 9, 33, 49, 50, 31, 60 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Length of Longest alternating "
<< "subsequence is " << zzis(arr, n);
return 0;
}
// This code is contributed by shivanisinghss2110
C
// C program to find longest alternating subsequence in
// an array
#include <stdio.h>
#include <stdlib.h>
// function to return max of two numbers
int max(int a, int b) { return (a > b) ? a : b; }
// Function to return longest alternating subsequence length
int zzis(int arr[], int n)
{
/*las[i][0] = Length of the longest alternating
subsequence ending at index i and last element is
greater than its previous element las[i][1] = Length of
the longest alternating subsequence ending at index i
and last element is smaller than its previous element
*/
int las[n][2];
/* Initialize all values from 1 */
for (int i = 0; i < n; i++)
las[i][0] = las[i][1] = 1;
int res = 1; // Initialize result
/* Compute values in bottom up manner */
for (int i = 1; i < n; i++) {
// Consider all elements as previous of arr[i]
for (int j = 0; j < i; j++) {
// If arr[i] is greater, then check with
// las[j][1]
if (arr[j] < arr[i]
&& las[i][0] < las[j][1] + 1)
las[i][0] = las[j][1] + 1;
// If arr[i] is smaller, then check with
// las[j][0]
if (arr[j] > arr[i]
&& las[i][1] < las[j][0] + 1)
las[i][1] = las[j][0] + 1;
}
/* Pick maximum of both values at index i */
if (res < max(las[i][0], las[i][1]))
res = max(las[i][0], las[i][1]);
}
return res;
}
/* Driver code */
int main()
{
int arr[] = { 10, 22, 9, 33, 49, 50, 31, 60 };
int n = sizeof(arr) / sizeof(arr[0]);
printf(
"Length of Longest alternating subsequence is %d\n",
zzis(arr, n));
return 0;
}
Java
// Java program to find longest
// alternating subsequence in an array
import java.io.*;
class GFG {
// Function to return longest
// alternating subsequence length
static int zzis(int arr[], int n)
{
/*las[i][0] = Length of the longest
alternating subsequence ending at
index i and last element is
greater than its previous element
las[i][1] = Length of the longest
alternating subsequence ending at
index i and last element is
smaller than its previous
element */
int las[][] = new int[n][2];
/* Initialize all values from 1 */
for (int i = 0; i < n; i++)
las[i][0] = las[i][1] = 1;
int res = 1; // Initialize result
/* Compute values in bottom up manner */
for (int i = 1; i < n; i++) {
// Consider all elements as
// previous of arr[i]
for (int j = 0; j < i; j++) {
// If arr[i] is greater, then
// check with las[j][1]
if (arr[j] < arr[i]
&& las[i][0] < las[j][1] + 1)
las[i][0] = las[j][1] + 1;
// If arr[i] is smaller, then
// check with las[j][0]
if (arr[j] > arr[i]
&& las[i][1] < las[j][0] + 1)
las[i][1] = las[j][0] + 1;
}
/* Pick maximum of both values at
index i */
if (res < Math.max(las[i][0], las[i][1]))
res = Math.max(las[i][0], las[i][1]);
}
return res;
}
/* Driver code*/
public static void main(String[] args)
{
int arr[] = { 10, 22, 9, 33, 49, 50, 31, 60 };
int n = arr.length;
System.out.println("Length of Longest "
+ "alternating subsequence is "
+ zzis(arr, n));
}
}
// This code is contributed by Prerna Saini
Python3
# Python3 program to find longest
# alternating subsequence in an array
# Function to return max of two numbers
def Max(a, b):
if a > b:
return a
else:
return b
# Function to return longest alternating
# subsequence length
def zzis(arr, n):
"""las[i][0] = Length of the longest
alternating subsequence ending at
index i and last element is greater
than its previous element
las[i][1] = Length of the longest
alternating subsequence ending
at index i and last element is
smaller than its previous element"""
las = [[0 for i in range(2)]
for j in range(n)]
# Initialize all values from 1
for i in range(n):
las[i][0], las[i][1] = 1, 1
# Initialize result
res = 1
# Compute values in bottom up manner
for i in range(1, n):
# Consider all elements as
# previous of arr[i]
for j in range(0, i):
# If arr[i] is greater, then
# check with las[j][1]
if (arr[j] < arr[i] and
las[i][0] < las[j][1] + 1):
las[i][0] = las[j][1] + 1
# If arr[i] is smaller, then
# check with las[j][0]
if(arr[j] > arr[i] and
las[i][1] < las[j][0] + 1):
las[i][1] = las[j][0] + 1
# Pick maximum of both values at index i
if (res < max(las[i][0], las[i][1])):
res = max(las[i][0], las[i][1])
return res
# Driver Code
arr = [10, 22, 9, 33, 49, 50, 31, 60]
n = len(arr)
print("Length of Longest alternating subsequence is",
zzis(arr, n))
# This code is contributed by divyesh072019
C#
// C# program to find longest
// alternating subsequence
// in an array
using System;
class GFG {
// Function to return longest
// alternating subsequence length
static int zzis(int[] arr, int n)
{
/*las[i][0] = Length of the
longest alternating subsequence
ending at index i and last
element is greater than its
previous element
las[i][1] = Length of the longest
alternating subsequence ending at
index i and last element is
smaller than its previous
element */
int[, ] las = new int[n, 2];
/* Initialize all values from 1 */
for (int i = 0; i < n; i++)
las[i, 0] = las[i, 1] = 1;
// Initialize result
int res = 1;
/* Compute values in
bottom up manner */
for (int i = 1; i < n; i++) {
// Consider all elements as
// previous of arr[i]
for (int j = 0; j < i; j++) {
// If arr[i] is greater, then
// check with las[j][1]
if (arr[j] < arr[i]
&& las[i, 0] < las[j, 1] + 1)
las[i, 0] = las[j, 1] + 1;
// If arr[i] is smaller, then
// check with las[j][0]
if (arr[j] > arr[i]
&& las[i, 1] < las[j, 0] + 1)
las[i, 1] = las[j, 0] + 1;
}
/* Pick maximum of both
values at index i */
if (res < Math.Max(las[i, 0], las[i, 1]))
res = Math.Max(las[i, 0], las[i, 1]);
}
return res;
}
// Driver Code
public static void Main()
{
int[] arr = { 10, 22, 9, 33, 49, 50, 31, 60 };
int n = arr.Length;
Console.WriteLine("Length of Longest "
+ "alternating subsequence is "
+ zzis(arr, n));
}
}
// This code is contributed by anuj_67.
PHP
<?php
// PHP program to find longest
// alternating subsequence in
// an array
// Function to return longest
// alternating subsequence length
function zzis($arr, $n)
{
/*las[i][0] = Length of the
longest alternating subsequence
ending at index i and last element
is greater than its previous element
las[i][1] = Length of the longest
alternating subsequence ending at
index i and last element is
smaller than its previous element */
$las = array(array());
/* Initialize all values from 1 */
for ( $i = 0; $i < $n; $i++)
$las[$i][0] = $las[$i][1] = 1;
$res = 1; // Initialize result
/* Compute values in
bottom up manner */
for ( $i = 1; $i < $n; $i++)
{
// Consider all elements
// as previous of arr[i]
for ($j = 0; $j < $i; $j++)
{
// If arr[i] is greater, then
// check with las[j][1]
if ($arr[$j] < $arr[$i] and
$las[$i][0] < $las[$j][1] + 1)
$las[$i][0] = $las[$j][1] + 1;
// If arr[i] is smaller, then
// check with las[j][0]
if($arr[$j] > $arr[$i] and
$las[$i][1] < $las[$j][0] + 1)
$las[$i][1] = $las[$j][0] + 1;
}
/* Pick maximum of both
values at index i */
if ($res < max($las[$i][0], $las[$i][1]))
$res = max($las[$i][0], $las[$i][1]);
}
return $res;
}
// Driver Code
$arr = array(10, 22, 9, 33,
49, 50, 31, 60 );
$n = count($arr);
echo "Length of Longest alternating " .
"subsequence is ", zzis($arr, $n) ;
// This code is contributed by anuj_67.
?>
JavaScript
<script>
// Javascript program to find longest
// alternating subsequence in an array
// Function to return longest
// alternating subsequence length
function zzis(arr, n)
{
/*las[i][0] = Length of the longest
alternating subsequence ending at
index i and last element is
greater than its previous element
las[i][1] = Length of the longest
alternating subsequence ending at
index i and last element is
smaller than its previous
element */
let las = new Array(n);
for (let i = 0; i < n; i++)
{
las[i] = new Array(2);
for (let j = 0; j < 2; j++)
{
las[i][j] = 0;
}
}
/* Initialize all values from 1 */
for (let i = 0; i < n; i++)
las[i][0] = las[i][1] = 1;
let res = 1; // Initialize result
/* Compute values in bottom up manner */
for (let i = 1; i < n; i++)
{
// Consider all elements as
// previous of arr[i]
for (let j = 0; j < i; j++)
{
// If arr[i] is greater, then
// check with las[j][1]
if (arr[j] < arr[i] &&
las[i][0] < las[j][1] + 1)
las[i][0] = las[j][1] + 1;
// If arr[i] is smaller, then
// check with las[j][0]
if( arr[j] > arr[i] &&
las[i][1] < las[j][0] + 1)
las[i][1] = las[j][0] + 1;
}
/* Pick maximum of both values at
index i */
if (res < Math.max(las[i][0], las[i][1]))
res = Math.max(las[i][0], las[i][1]);
}
return res;
}
let arr = [ 10, 22, 9, 33, 49, 50, 31, 60 ];
let n = arr.length;
document.write("Length of Longest "+
"alternating subsequence is " +
zzis(arr, n));
// This code is contributed by rameshtravel07.
</script>
OutputLength of Longest alternating subsequence is 6
Time Complexity: O(N2)
Auxiliary Space: O(N), since N extra space has been taken
Efficient Approach: To solve the problem follow the below idea:
In the above approach, at any moment we are keeping track of two values (The length of the longest alternating subsequence ending at index i, and the last element is smaller than or greater than the previous element), for every element on the array. To optimize space, we only need to store two variables for element at any index i
inc = Length of longest alternative subsequence so far with current value being greater than it's previous value.
dec = Length of longest alternative subsequence so far with current value being smaller than it's previous value.
The tricky part of this approach is to update these two values.
"inc" should be increased, if and only if the last element in the alternative sequence was smaller than it's previous element.
"dec" should be increased, if and only if the last element in the alternative sequence was greater than it's previous element.
Follow the below steps to solve the problem:
- Declare two integers inc and dec equal to one
- Run a loop for i [1, N-1]
- If arr[i] is greater than the previous element then set inc equal to dec + 1
- Else if arr[i] is smaller than the previous element then set dec equal to inc + 1
- Return maximum of inc and dec
Below is the implementation of the above approach:
C++
// C++ program for above approach
#include <bits/stdc++.h>
using namespace std;
// Function for finding
// longest alternating
// subsequence
int LAS(int arr[], int n)
{
// "inc" and "dec" initialized as 1
// as single element is still LAS
int inc = 1;
int dec = 1;
// Iterate from second element
for (int i = 1; i < n; i++) {
if (arr[i] > arr[i - 1]) {
// "inc" changes if "dec"
// changes
inc = dec + 1;
}
else if (arr[i] < arr[i - 1]) {
// "dec" changes if "inc"
// changes
dec = inc + 1;
}
}
// Return the maximum length
return max(inc, dec);
}
// Driver Code
int main()
{
int arr[] = { 10, 22, 9, 33, 49, 50, 31, 60 };
int n = sizeof(arr) / sizeof(arr[0]);
// Function Call
cout << LAS(arr, n) << endl;
return 0;
}
Java
// Java Program for above approach
public class GFG {
// Function for finding
// longest alternating
// subsequence
static int LAS(int[] arr, int n)
{
// "inc" and "dec" initialized as 1,
// as single element is still LAS
int inc = 1;
int dec = 1;
// Iterate from second element
for (int i = 1; i < n; i++) {
if (arr[i] > arr[i - 1]) {
// "inc" changes if "dec"
// changes
inc = dec + 1;
}
else if (arr[i] < arr[i - 1]) {
// "dec" changes if "inc"
// changes
dec = inc + 1;
}
}
// Return the maximum length
return Math.max(inc, dec);
}
// Driver Code
public static void main(String[] args)
{
int[] arr = { 10, 22, 9, 33, 49, 50, 31, 60 };
int n = arr.length;
// Function Call
System.out.println(LAS(arr, n));
}
}
Python3
# Python3 program for above approach
def LAS(arr, n):
# "inc" and "dec" initialized as 1
# as single element is still LAS
inc = 1
dec = 1
# Iterate from second element
for i in range(1, n):
if (arr[i] > arr[i-1]):
# "inc" changes if "dec"
# changes
inc = dec + 1
elif (arr[i] < arr[i-1]):
# "dec" changes if "inc"
# changes
dec = inc + 1
# Return the maximum length
return max(inc, dec)
# Driver Code
if __name__ == "__main__":
arr = [10, 22, 9, 33, 49, 50, 31, 60]
n = len(arr)
# Function Call
print(LAS(arr, n))
C#
// C# program for above approach
using System;
class GFG {
// Function for finding
// longest alternating
// subsequence
static int LAS(int[] arr, int n)
{
// "inc" and "dec" initialized as 1,
// as single element is still LAS
int inc = 1;
int dec = 1;
// Iterate from second element
for (int i = 1; i < n; i++) {
if (arr[i] > arr[i - 1]) {
// "inc" changes if "dec"
// changes
inc = dec + 1;
}
else if (arr[i] < arr[i - 1]) {
// "dec" changes if "inc"
// changes
dec = inc + 1;
}
}
// Return the maximum length
return Math.Max(inc, dec);
}
// Driver code
static void Main()
{
int[] arr = { 10, 22, 9, 33, 49, 50, 31, 60 };
int n = arr.Length;
// Function Call
Console.WriteLine(LAS(arr, n));
}
}
// This code is contributed by divyeshrabadiya07
JavaScript
<script>
// Javascript program for above approach
// Function for finding
// longest alternating
// subsequence
function LAS(arr, n)
{
// "inc" and "dec" initialized as 1
// as single element is still LAS
let inc = 1;
let dec = 1;
// Iterate from second element
for (let i = 1; i < n; i++)
{
if (arr[i] > arr[i - 1])
{
// "inc" changes if "dec"
// changes
inc = dec + 1;
}
else if (arr[i] < arr[i - 1])
{
// "dec" changes if "inc"
// changes
dec = inc + 1;
}
}
// Return the maximum length
return Math.max(inc, dec);
}
let arr = [ 10, 22, 9, 33, 49, 50, 31, 60 ];
let n = arr.length;
// Function Call
document.write(LAS(arr, n));
// This code is contributed by mukesh07.
</script>
Output:
6
Time Complexity: O(N)
Auxiliary Space: O(1)
Similar Reads
Longest Decreasing Subsequence
Given an array of N integers, find the length of the longest subsequence of a given sequence such that all elements of the subsequence are sorted in strictly decreasing order. Examples: Input: arr[] = [15, 27, 14, 38, 63, 55, 46, 65, 85] Output: 3 Explanation: The longest decreasing subsequence is {
14 min read
Longest alternative parity subsequence
We are given an array a of size N. The task is to print the length of the longest alternative odd/even or even/odd subsequence. Examples: Input: a[] = { 13, 16, 8, 9, 32, 10 } Output: 4 {13, 16, 9, 10} or any other subsequence of length 4 can be the answer. Input: a[] = {1, 2, 3, 3, 9} Output: 3 App
7 min read
Longest Balanced Subsequence
Given a string str, find the length of the longest balanced subsequence in it. A balanced string is defined as a string sequence that can form a valid balanced expression, consisting of matching opening and closing brackets. A null string is a balanced string.If X and Y are balanced strings, then (X
14 min read
Longest Bitonic Subsequence
Given an array arr[] containing n positive integers, a subsequence of numbers is called bitonic if it is first strictly increasing, then strictly decreasing. The task is to find the length of the longest bitonic subsequence. Note: Only strictly increasing (no decreasing part) or a strictly decreasin
15+ min read
Longest dividing subsequence
You are given an array A of size N. Your task is to find the length of largest dividing sub sequence.A dividing sequence is a sequence a1, a2, â¦, aN where ai divides aj whenever i < j. For example, 3, 15, 60, 720 is a dividing sequence. input- The first line of each test case is N, where N is the
5 min read
Longest Increasing Subsequence (LIS)
Given an array arr[] of size n, the task is to find the length of the Longest Increasing Subsequence (LIS) i.e., the longest possible subsequence in which the elements of the subsequence are sorted in increasing order.Examples: Input: arr[] = [3, 10, 2, 1, 20]Output: 3Explanation: The longest increa
14 min read
Longest subsequence having difference atmost K
Given a string S of length N and an integer K, the task is to find the length of longest sub-sequence such that the difference between the ASCII values of adjacent characters in the subsequence is not more than K. Examples: Input: N = 7, K = 2, S = "afcbedg" Output: 4 Explanation: Longest special se
8 min read
Longest Increasing consecutive subsequence
Given N elements, write a program that prints the length of the longest increasing consecutive subsequence. Examples: Input : a[] = {3, 10, 3, 11, 4, 5, 6, 7, 8, 12} Output : 6 Explanation: 3, 4, 5, 6, 7, 8 is the longest increasing subsequence whose adjacent element differs by one. Input : a[] = {6
10 min read
Longest Consecutive Subsequence
Given an array of integers, the task is to find the length of the longest subsequence such that elements in the subsequence are consecutive integers, the consecutive numbers can be in any order. Examples: Input: arr[] = [2, 6, 1, 9, 4, 5, 3]Output: 6Explanation: The consecutive numbers here are from
9 min read
Longest Increasing Odd Even Subsequence
Given an array of size n. The problem is to find the length of the subsequence in the given array such that all the elements of the subsequence are sorted in increasing order and also they are alternately odd and even. Note that the subsequence could start either with the odd number or with the even
8 min read