给定一个仅包含正数和负数的数组arr[] 。任务是找到数组中存在的最长交替(意味着负-正-负或正-负-正)子序列的长度。
例子:
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.
方法:
这个问题可以用动态规划解决。它是最长递增子序列(LIS)的变体。以下是步骤:
- 为了在给定数组arr[] 中包含和排除 LAS(最长替代子序列)中的元素,使用变量pos ,当pos = true 表示当前元素需要为正时,如果pos = false 则当前元素需要为消极的。
- 如果我们包含当前元素,则为下一个元素更改pos和 recurr 的值,因为我们需要与先前包含的元素相反的下一个元素。
- 现在LAS[i][pos]可以递归地写为:
- 基本情况:如果递归调用的索引大于最后一个元素,则返回 0,因为没有这样的元素可以形成 LAS,如果计算LAS[i][pos] ,则返回值。
if(i == N) {
return 0;
}
if(LAS[i][pos]) {
return LAS[i][pos];
}
- 递归调用:如果不满足基本情况,则在包含和排除当前元素时递归调用,然后找到在该索引处找到 LAS 的最大值。
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));
- 返回语句:在每次递归调用时(基本情况除外),返回LAS[i][pos] 的值。
return LAS[i][pos];
- 给定数组arr[]的 LAS 是 LAS[0][0] 和 LAS[0][1] 的最大值。
下面是上述方法的实现:
C++
// C++ program to find the
// length of longest alternate
// subsequence
#include
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;
// 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 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;
// 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 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;
# 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 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;
// 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 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
5
时间复杂度: O(N),其中 N 是数组的长度。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。