📜  最长的交替子序列,具有最大的元素总数

📅  最后修改于: 2021-05-17 18:00:58             🧑  作者: Mango

给定长度为N的列表,其中包含正整数和负整数。任务是选择给定序列的最长交替子序列(即,每个下一个元素的符号与当前元素的符号相反)。在所有这些子序列中,我们必须选择一个具有最大元素总和的子序列,并显示该总和。
例子:

方法:可以通过以下方法达到解决方案:

  • 为了获得具有最大长度和最大和的交替子序列,我们将遍历整个列表(列表的长度)-1次以比较连续元素的符号。
  • 在遍历期间,如果我们得到多个1个相同符号的连续元素(exp。1 2 4),那么我们会将其中最大的元素追加到另一个名为large的列表中。因此,从1 2和4开始,我们会将4附加到另一个列表中。
  • 如果我们有连续的相反符号的元素,我们将简单地将那些元素添加到名为large的列表中。
  • 最终,名为large的列表将具有最长的交替子序列和最大的元素。
  • 现在,我们将必须计算该列表中名为large的所有元素的总和。

下面是上述方法的实现:

C++
// C++ implementation to find the 
// longest alternating subsequence 
// which has the maximum sum
#include
using namespace std;
  
int calculateMaxSum(int n, int li[])
{
      
    // Creating a temporary list ar to 
    // every time store same sign element
    // to calculate maximum element from 
    // that list ar
    vector ar;
      
    // Appending 1st element of list li 
    // to the ar
    ar.push_back(li[0]);
      
    // Creating list to store maximum 
    // values 
    vector large;
  
    for(int j = 0; j < n - 1; j++)
    {
         
       // If both number are positive 
       // then append (j + 1)th element 
       // to temporary list ar
       if(li[j] > 0 and li[j + 1] > 0)
       {
           ar.push_back(li[j + 1]);
       }
       else if(li[j] > 0 and li[j + 1] < 0)
       {
             
           // If opposite elements found 
           // then append maximum element 
           // to large list
           large.push_back(*max_element(ar.begin(), 
                                        ar.end()));
                                          
           // Empty ar list to re-append
           // next elements 
           ar.clear();
           ar.push_back(li[j + 1]);
       }
       else if(li[j] < 0 and li[j + 1] > 0)
       {
             
           // If opposite elements found 
           // then append maximum element
           // to large list
           large.push_back(*max_element(ar.begin(),
                                        ar.end()));
             
           // Empty ar list to re-append 
           // next elements 
           ar.clear();
           ar.push_back(li[j + 1]);
       }
       else
       {
           // If both number are negative
           // then append (j + 1)th element
           // to temporary list ar 
           ar.push_back(li[j + 1]);
       }
    }
      
    // The final Maximum element in ar list
    // also needs to be appended to large list 
    large.push_back(*max_element(ar.begin(),
                                 ar.end()));
      
    // Returning the sum of all elements 
    // from largest elements list with
    // largest alternating subsequence size
    int sum = 0;
    for(int i = 0; i < large.size(); i++)
       sum += large[i];
    return sum;
}
      
// Driver code
int main()
{
    int list[] = { -2, 8, 3, 8, -4, -15,
                    5, -2, -3, 1 };
    int N = sizeof(list) / sizeof(list[0]);
  
    cout << (calculateMaxSum(N, list));
}
  
// This code is contributed by Bhupendra_Singh


Java
// Java implementation to find the 
// longest alternating subsequence 
// which has the maximum sum 
import java.util.*;
  
class GFG{
  
static int calculateMaxSum(int n, int li[]) 
{ 
      
    // Creating a temporary list ar to 
    // every time store same sign element 
    // to calculate maximum element from 
    // that list ar 
    Vector ar = new Vector<>(); 
      
    // Appending 1st element of list li 
    // to the ar 
    ar.add(li[0]); 
      
    // Creating list to store maximum 
    // values 
    Vector large = new Vector<>();
  
    for(int j = 0; j < n - 1; j++) 
    { 
          
        // If both number are positive 
        // then append (j + 1)th element 
        // to temporary list ar 
        if(li[j] > 0 && li[j + 1] > 0) 
        { 
            ar.add(li[j + 1]); 
        } 
        else if(li[j] > 0 && li[j + 1] < 0) 
        { 
                  
            // If opposite elements found 
            // then append maximum element 
            // to large list 
            large.add(Collections.max(ar)); 
                                              
            // Empty ar list to re-append 
            // next elements 
            ar.clear(); 
            ar.add(li[j + 1]); 
        } 
        else if(li[j] < 0 && li[j + 1] > 0) 
        { 
                  
            // If opposite elements found 
            // then append maximum element 
            // to large list 
            large.add(Collections.max(ar)); 
                  
            // Empty ar list to re-append 
            // next elements 
            ar.clear(); 
            ar.add(li[j + 1]); 
        } 
        else
        { 
            // If both number are negative 
            // then append (j + 1)th element 
            // to temporary list ar 
            ar.add(li[j + 1]); 
        } 
    } 
      
    // The final Maximum element in ar list 
    // also needs to be appended to large list 
    large.add(Collections.max(ar)); 
      
    // Returning the sum of all elements 
    // from largest elements list with 
    // largest alternating subsequence size 
    int sum = 0; 
    for(int i = 0; i < large.size(); i++) 
        sum += (int)large.get(i); 
          
    return sum; 
} 
  
// Driver code
public static void main(String args[]) 
{ 
    int list[] = { -2, 8, 3, 8, -4, -15, 
                    5, -2, -3, 1 }; 
    int N = (list.length);
      
    System.out.print(calculateMaxSum(N, list));
}
}
  
// This code is contributed by Stream_Cipher


Python3
# Python3 implementation to find the 
# longest alternating subsequence 
# which has the maximum sum
  
def calculateMaxSum(n, li):
    # Creating a temporary list ar to every
    # time store same sign element to 
    # calculate maximum element from 
    # that list ar
    ar =[]
      
    # Appending 1st element of list li 
    # to the ar
    ar.append(li[0])
      
    # Creating list to store maximum 
    # values 
    large =[]
      
    for j in range(0, n-1):
          
        # If both number are positive 
        # then append (j + 1)th element 
        # to temporary list ar
        if(li[j]>0 and li[j + 1]>0):
            ar.append(li[j + 1])
        elif(li[j]>0 and li[j + 1]<0):
              
            # If opposite elements found 
            # then append maximum element 
            # to large list
            large.append(max(ar))
              
            # Empty ar list to re-append
            # next elements  
            ar =[]
            ar.append(li[j + 1])
        elif(li[j]<0 and li[j + 1]>0):
              
            # If opposite elements found 
            # then append maximum element
            # to large list
            large.append(max(ar))
              
            # Empty ar list to re-append 
            # next elements 
            ar =[]
            ar.append(li[j + 1])
        else:
            # If both number are negative
            # then append (j + 1)th element
            # to temporary list ar 
            ar.append(li[j + 1])
              
    # The final Maximum element in ar list
    # also needs to be appended to large list 
    large.append(max(ar))
      
    # returning the sum of all elements 
    # from largest elements list with
    # largest alternating subsequence size
    return sum(large)
  
  
# Driver code
list =[-2, 8, 3, 8, -4, -15, 5, -2, -3, 1]
N = len(list)
  
print(calculateMaxSum(N, list))


C#
// C# implementation to find the 
// longest alternating subsequence 
// which has the maximum sum 
using System; 
using System.Collections.Generic;
  
class GFG{
  
static int find_max(List ar)
{
    int mx = -1000000;
    foreach(var i in ar)
    {
        if(i > mx)
           mx = i;
    }
    return mx;
}
  
static int calculateMaxSum(int n, int []li) 
{ 
      
    // Creating a temporary list ar to 
    // every time store same sign element 
    // to calculate maximum element from 
    // that list ar 
    List ar = new List();
      
    // Appending 1st element of list li 
    // to the ar 
    ar.Add(li[0]); 
      
    // Creating list to store maximum 
    // values 
    List large = new List();
  
    for(int j = 0; j < n - 1; j++) 
    { 
          
        // If both number are positive 
        // then append (j + 1)th element 
        // to temporary list ar 
        if(li[j] > 0 && li[j + 1] > 0) 
        { 
            ar.Add(li[j + 1]); 
        } 
        else if(li[j] > 0 && li[j + 1] < 0) 
        { 
                  
            // If opposite elements found 
            // then append maximum element 
            // to large list 
            large.Add(find_max(ar)); 
                                              
            // Empty ar list to re-append 
            // next elements 
            ar.Clear(); 
            ar.Add(li[j + 1]); 
        } 
        else if(li[j] < 0 && li[j + 1] > 0) 
        { 
                  
            // If opposite elements found 
            // then append maximum element 
            // to large list 
            large.Add(find_max(ar)); 
                  
            // Empty ar list to re-append 
            // next elements 
            ar.Clear(); 
            ar.Add(li[j + 1]); 
        } 
        else
        { 
              
            // If both number are negative 
            // then append (j + 1)th element 
            // to temporary list ar 
            ar.Add(li[j + 1]); 
        } 
    } 
      
    // The final Maximum element in ar list 
    // also needs to be appended to large list 
    large.Add(find_max(ar)); 
      
    // Returning the sum of all elements 
    // from largest elements list with 
    // largest alternating subsequence size 
    int sum = 0;
    foreach(var i in large)
    {
        sum += i;
    }
    return sum; 
} 
  
// Driver code
public static void Main() 
{ 
    int []list = { -2, 8, 3, 8, -4, -15, 
                    5, -2, -3, 1 }; 
    int N = (list.Length);
      
    Console.WriteLine(calculateMaxSum(N, list));
}
}
  
// This code is contributed by Stream_Cipher


输出:
6

时间复杂度: O(N)