如果序列{x1,x2,.. xn}的元素满足以下关系之一,则为交替序列:
x1 < x2 > x3 < x4 > x5 < …. xn or
x1 > x2 < x3 > x4 < x5 > …. xn
例子 :
Input: arr[] = {1, 5, 4}
Output: 3
The whole arrays is of the form x1 < x2 > x3
Input: arr[] = {1, 4, 5}
Output: 2
All subsequences of length 2 are either of the form
x1 < x2; or x1 > x2
Input: arr[] = {10, 22, 9, 33, 49, 50, 31, 60}
Output: 6
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.
这个问题是最长增长子序列问题的扩展,但是需要更多的思考才能找到最佳的子结构属性。
我们将通过动态编程的方法来解决这个问题,设A为长度为n的整数数组。我们定义一个2D数组las [n] [2],使得las [i] [0]包含以索引i结尾的最长交替子序列,而最后一个元素大于其前一个元素,而las [i] [1]包含最长的交替子序列在索引i处结束并且最后一个元素小于它的前一个元素,那么我们具有以下它们之间的递归关系,
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]
第一个递归关系基于以下事实:如果我们在位置i处并且该元素必须大于其先前的元素,则为了使此序列(直到i)更大,我们将尝试选择元素j(请记住,我们选择las [j] [1] + 1而不是las [j] [0] +1是为了满足替代属性,因为在las [j] [0]中,最后一个元素大于前一个元素,而A [i]为大于A [j],如果我们更新,它将破坏交替属性。因此,以上事实得出第一递归关系,第二递归关系也可以作类似的论证。
C++
// C++ program to find longest alternating
// subsequence in an array
#include
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
#include
// 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 program */
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 program */
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
$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.
?>
C++
// C++ program for above approach
#include
using namespace std;
// Function for finding
// longest alternating
// subsequence
int LAS(int arr[], int n)
{
// "inc" and "dec" intialized 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 iff "dec"
// changes
inc = dec + 1;
}
else if (arr[i] < arr[i - 1])
{
// "dec" changes iff "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" intialized 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 iff "dec"
// changes
inc = dec + 1;
}
else if (arr[i] < arr[i - 1])
{
// "dec" changes iff "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" intialized 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 iff "dec"
# changes
inc = dec + 1
elif (arr[i] < arr[i-1]):
# "dec" changes iff "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" intialized 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 iff "dec"
// changes
inc = dec + 1;
}
else if (arr[i] < arr[i - 1])
{
// "dec" changes iff "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
输出:
Length of Longest alternating subsequence is 6
时间复杂度: O(n 2 )
辅助空间: O(n)
高效的解决方案:
在上述方法中,对于数组中的每个元素,我们随时都在跟踪两个值(最长的交替子序列的长度在索引i处结束,最后一个元素小于或大于前一个元素)。为了优化空间,我们只需要在任何索引i处为元素存储两个变量。
inc =到目前为止,最长替代子序列的长度,当前值大于以前的值。
dec =到目前为止,最长替代子序列的长度,当前值小于以前的值。
这种方法的棘手部分是更新这两个值。
当且仅当替代序列中的最后一个元素小于前一个元素时,才应增加“ inc”。
当且仅当替代序列中的最后一个元素大于前一个元素时,才应增加“ dec”。
C++
// C++ program for above approach
#include
using namespace std;
// Function for finding
// longest alternating
// subsequence
int LAS(int arr[], int n)
{
// "inc" and "dec" intialized 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 iff "dec"
// changes
inc = dec + 1;
}
else if (arr[i] < arr[i - 1])
{
// "dec" changes iff "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" intialized 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 iff "dec"
// changes
inc = dec + 1;
}
else if (arr[i] < arr[i - 1])
{
// "dec" changes iff "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" intialized 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 iff "dec"
# changes
inc = dec + 1
elif (arr[i] < arr[i-1]):
# "dec" changes iff "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" intialized 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 iff "dec"
// changes
inc = dec + 1;
}
else if (arr[i] < arr[i - 1])
{
// "dec" changes iff "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
Java脚本
输出:
6
时间复杂度: O(n)
辅助空间: O(1)