给定大小为N的数组arr [] ,该数组由正整数和负整数组成,任务是从给定数组中找到最长的交替子序列(即,每个元素的符号与其前一个元素的符号相反)和。
例子:
Input: arr[] = {-2, 10, 3, -8, -4, -1, 5, -2, -3, 1}
Output: 11
Explanation:
Since the subsequence needs to be longest possible as well as alternating, one element can be selected from each of the following subarrays:
{-2}, {10, 3}, {-8, -4, -1}, {5}, {-2, -3}, {1}
Hence, selecting the maximum from each of the subarrays as the elements of the subsequence generates an alternating subsequence with maximum sum.
Therefore, the subsequence is {-2, 10, -1, 5, -2, 1}
Hence, the sum of the subsequence is 11.
Input: arr[] = {12, 4, -5, 7, -9}
Output: 5
Explanation:
The longest subsequence with greatest sum is {12, -5, 7, -9}.
Hence, the maximum sum is 5.
使用多余空间的线性方法:
有关使用额外空间的线性方法,请参阅最长交替子序列,该子序列具有最大的元素总和。
时间复杂度: O(N)
辅助空间: O(N)
节省空间的方法:
为了解决该问题,我们可以观察以下内容:
- 为了最大程度地增加交替子序列的长度,我们需要考虑序列中每个连续数的元素
Illustration:
Let us consider an array arr[] = {1, 1, 2, -1, -5, 2, 1, -3}
The consecutive sequences of elements of same sign are:
{1, 1, 2}, {-1, -5}, {2, 1}, {-3}
Hence, by selecting an element from each of these sequences, an alternating subsequence of the longest possible length can be obtained.
- 为了最大化子序列的总和,我们需要从相同符号的元素的每个连续子序列中选择最大值。
Illustration:
For the array arr[] = {1, 1, 2, -1, -5, 2, 1, -3}, the consecutive sequences of elements of sign were observed to be:
{1, 1, 2}, {-1, -5}, {2, 1}, {-3}
Therefore, the subsequence with the maximum sum is {2, -1, 2, -3}, formed by selecting the maximum element from each of the sequences.
请按照以下步骤有效地解决问题:
- 使用两个指针迭代数组。
- 设置i = 0 ,并设置j = i 。
- 遍历数组,直到j指向一个索引,该索引由与arr [i]相对的正负号元素组成。每次遍历时,更新[i,j]之间遇到的最大元素。
- 找到相反符号的元素后,将序列[i,j)中的最大值加到maxsum 。
- 设置i = j ,并重复上述两个步骤,直到遍历整个数组。
- 打印maxsum的最终值作为答案。
下面是上述方法的实现:
C++
// C++ Program to implement
// the above approach
#include
using namespace std;
// Function to check the
// sign of the element
int sign(int x)
{
if (x > 0)
return 1;
else
return -1;
}
// Function to calculate and
// return the maximum sum of
// longest alternating subsequence
int findMaxSum(int arr[], int size)
{
int max_sum = 0, pres, i, j;
// Iterate through the array
for (i = 0; i < size; i++) {
// Stores the first element of
// a sequence of same sign
pres = arr[i];
j = i;
// Traverse until an element with
// opposite sign is encountered
while (j < size
&& sign(arr[i])
== sign(arr[j])) {
// Update the maximum
pres = max(pres, arr[j]);
j++;
}
// Update the maximum sum
max_sum = max_sum + pres;
// Update i
i = j - 1;
}
// Return the maximum sum
return max_sum;
}
// Driver Code
int main()
{
int arr[] = { -2, 8, 3, 8, -4,
-15, 5, -2, -3, 1 };
int size = sizeof(arr)
/ sizeof(arr[0]);
cout << findMaxSum(arr, size);
return 0;
}
Java
// Java Program to implement
// the above approach
import java.util.*;
class GFG{
// Function to check the
// sign of the element
static int sign(int x)
{
if (x > 0)
return 1;
else
return -1;
}
// Function to calculate and
// return the maximum sum of
// longest alternating subsequence
static int findMaxSum(int arr[], int size)
{
int max_sum = 0, pres, i, j;
// Iterate through the array
for (i = 0; i < size; i++)
{
// Stores the first element of
// a sequence of same sign
pres = arr[i];
j = i;
// Traverse until an element with
// opposite sign is encountered
while (j < size &&
sign(arr[i]) == sign(arr[j]))
{
// Update the maximum
pres = Math.max(pres, arr[j]);
j++;
}
// Update the maximum sum
max_sum = max_sum + pres;
// Update i
i = j - 1;
}
// Return the maximum sum
return max_sum;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { -2, 8, 3, 8, -4, -15, 5, -2, -3, 1 };
int size = arr.length;
System.out.println(findMaxSum(arr, size));
}
}
// This code is contributed by sapnasingh4991
Python
# Python3 program to implement
# the above approach
# Function to check the
# sign of the element
def sign(x):
if (x > 0):
return 1
else:
return -1
# Function to calculate and
# return the maximum sum of
# longest alternating subsequence
def findMaxSum(arr, size):
max_sum = 0
# Iterate through the array
i = 0
while i < size:
# Stores the first element of
# a sequence of same sign
pres = arr[i]
j = i
# Traverse until an element with
# opposite sign is encountered
while (j < size and
(sign(arr[i]) == sign(arr[j]))):
# Update the maximum
pres = max(pres, arr[j])
j += 1
# Update the maximum sum
max_sum = max_sum + pres
# Update i
i = j - 1
i += 1
# Return the maximum sum
return max_sum
# Driver Code
if __name__ == "__main__":
arr = [ -2, 8, 3, 8, -4,
-15, 5, -2, -3, 1 ]
size = len(arr)
print(findMaxSum(arr, size))
# This code is contributed by chitranayal
C#
// C# Program to implement
// the above approach
using System;
class GFG{
// Function to check the
// sign of the element
static int sign(int x)
{
if (x > 0)
return 1;
else
return -1;
}
// Function to calculate and
// return the maximum sum of
// longest alternating subsequence
static int findMaxSum(int []arr, int size)
{
int max_sum = 0, pres, i, j;
// Iterate through the array
for (i = 0; i < size; i++)
{
// Stores the first element of
// a sequence of same sign
pres = arr[i];
j = i;
// Traverse until an element with
// opposite sign is encountered
while (j < size &&
sign(arr[i]) == sign(arr[j]))
{
// Update the maximum
pres = Math.Max(pres, arr[j]);
j++;
}
// Update the maximum sum
max_sum = max_sum + pres;
// Update i
i = j - 1;
}
// Return the maximum sum
return max_sum;
}
// Driver Code
public static void Main(String[] args)
{
int []arr = { -2, 8, 3, 8, -4,
-15, 5, -2, -3, 1 };
int size = arr.Length;
Console.WriteLine(findMaxSum(arr, size));
}
}
// This code is contributed by gauravrajput1
6
时间复杂度: O(N)
辅助空间: O(1)