Open In App

Find heaviest increasing Subsequence with maximum sum in a String

Last Updated : 24 Jul, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a string s and an array arr[] representing the weights of each character in the string, the task is to find the heaviest increasing subsequence with the maximum sum and return that subsequence.

Examples:

Input: s = “acbde”, arr[] = {2, 4, 3, 5, 1}
Output: acd
Explanation: The heaviest increasing subsequence with the maximum sum is “acd” as the weights of characters a, c, and d are 2+4+5 = 11, which is the maximum possible sum.

Input: s = “pqrstuv”, arr[] = {2, 3, 1, 4, 6, 5, 8}
Output: pqstv
Explanation: The heaviest increasing subsequence with the maximum sum in “pqstv” as the weights of characters p, q, s, t, and v are 2+3+4+6+8 = 23, which is the maximum possible sum.

Approach: This can be solved with the following idea:

In this approach, we first create a vector of vectors to store all possible LIS of each element in the input array. Then, we find the LIS with the maximum sum, which represents the heaviest increasing subsequence. Finally, construct the subsequence using the indices of the elements in the LIS with the maximum sum, and return the corresponding characters from the input string.

Below are the steps of the above approach:

  • First, we create a vector of vectors called lis, where each lis[i] is a vector that stores the heaviest increasing subsequence that ends with arr[i].
  • We initialize each lis[i] to contain only the element arr[i] because any element can be considered as a trivial increasing subsequence of length 1.
  • We then iterate through each element arr[i] of the array, and for each arr[i], we compare it with all the previous elements arr[j] of the array where j < i. If arr[i] is greater than arr[j] and the length of lis[j] is greater than or equal to the length of lis[i] – 1, then we update lis[i] to be lis[j] followed by arr[i].
  • After we have generated all the lis vectors, we iterate through each lis[i] vector and calculate its sum. We then compare this sum with the current maximum sum and update the maximum sum and corresponding maxIndex vector if the current sum is greater.
  • Finally, we iterate through each element of the original string s and add it to the output string ans if its corresponding element in the arr vector is present in the maxIndex vector.

Below is the implementation of the above approach:

C++




// C++ code for thenabove approach:
#include <bits/stdc++.h>
using namespace std;
 
// Functiont to heaviest
// subsequence string
string heaviestIncreasingSubsequence(string s,
                                     vector<int>& arr)
{
 
    int n = s.size();
    vector<vector<int> > lis(n);
 
    for (int i = 0; i < n; i++) {
        lis[i].push_back(arr[i]);
 
        for (int j = 0; j < i; j++) {
            if (arr[j] < arr[i]
                && lis[j].size() > lis[i].size() - 1) {
                lis[i] = lis[j];
                lis[i].push_back(arr[i]);
            }
        }
    }
 
    // Intialize a maxSum by
    // a small number
    int maxSum = 0;
    vector<int> maxIndex;
 
    for (int i = 0; i < n; i++) {
        int sum
            = accumulate(lis[i].begin(), lis[i].end(), 0);
        if (sum > maxSum) {
            maxSum = sum;
            maxIndex = lis[i];
        }
    }
 
    string ans = "";
    for (int i = 0; i < n; i++) {
        if (find(maxIndex.begin(), maxIndex.end(), arr[i])
            != maxIndex.end()) {
            ans += s[i];
        }
    }
 
    return ans;
}
 
// Driver code
int main()
{
    string s = "pqrstuv";
    vector<int> arr = { 2, 3, 1, 4, 6, 5, 8 };
 
    // Function call
    string heaviestIS
        = heaviestIncreasingSubsequence(s, arr);
 
    cout << heaviestIS << endl;
 
    return 0;
}


Java




import java.util.ArrayList;
import java.util.List;
 
public class Main {
      // Functiont to heaviest
    // subsequence string
    public static String heaviestIncreasingSubsequence(String s, List<Integer> arr) {
        int n = s.length();
        List<List<Integer>> lis = new ArrayList<>();
       
    
        for (int i = 0; i < n; i++) {
            lis.add(new ArrayList<>());
            lis.get(i).add(arr.get(i));
           
            for (int j = 0; j < i; j++) {
               
              //  If arr[i] is greater than arr[j] and the length
              // of lis[j] is greater than or equal to the length of lis[i] – 1,
              // then we update lis[i] to be lis[j] followed by arr[i].
                if (arr.get(j) < arr.get(i) && lis.get(j).size() > lis.get(i).size() - 1) {
                    lis.set(i, new ArrayList<>(lis.get(j)));
                    lis.get(i).add(arr.get(i));
                }
            }
        }
    // Intialize a maxSum by
    // a small number
        int maxSum = 0;
        List<Integer> maxIndex = new ArrayList<>();
       
        for (int i = 0; i < n; i++) {
            int sum = 0;
            for (int num : lis.get(i)) {
                sum += num;
            }
            if (sum > maxSum) {
                maxSum = sum;
                maxIndex = lis.get(i);
            }
        }
 
          //iterate through each element of the original string s and
          // add it to the output string ans if its corresponding element
        // in the arr vector is present in the maxIndex vector.
        StringBuilder ans = new StringBuilder();
        for (int i = 0; i < n; i++) {
            if (maxIndex.contains(arr.get(i))) {
                ans.append(s.charAt(i));
            }
        }
        return ans.toString();
    }
 
 // Driver code
    public static void main(String[] args) {
        String s = "pqrstuv";
        List<Integer> arr = List.of(2, 3, 1, 4, 6, 5, 8);
 
      // Function call
        String heaviestIS = heaviestIncreasingSubsequence(s, arr);
        System.out.println(heaviestIS);
    }
}


Python3




# Python code for the above approach
 
from typing import List
 
def heaviestIncreasingSubsequence(s: str, arr: List[int]) -> str:
    n = len(s)
    lis = [[] for _ in range(n)]
 
    # Generate Longest Increasing Subsequences for each element
    for i in range(n):
        lis[i].append(arr[i])
 
        for j in range(i):
            if arr[j] < arr[i] and len(lis[j]) > len(lis[i]) - 1:
                lis[i] = lis[j] + [arr[i]]
 
    maxSum = 0
    maxIndex = []
 
    # Find the LIS with the maximum sum
    for i in range(n):
        _sum = sum(lis[i])
        if _sum > maxSum:
            maxSum = _sum
            maxIndex = lis[i]
 
    ans = ""
    for i in range(n):
        if arr[i] in maxIndex:
            ans += s[i]
 
    return ans
 
if __name__ == "__main__":
    s = "pqrstuv"
    arr = [2, 3, 1, 4, 6, 5, 8]
 
    heaviestIS = heaviestIncreasingSubsequence(s, arr)
    print(heaviestIS)


C#




using System;
using System.Collections.Generic;
using System.Linq;
 
class Program
{
   
// Functiont to heaviest
// subsequence string
    static string HeaviestIncreasingSubsequence(string s, List<int> arr)
    {
        int n = s.Length;
        List<List<int>> lis = new List<List<int>>(n);
        for (int i = 0; i < n; i++)
        {
            lis.Add(new List<int>());
            lis[i].Add(arr[i]);
            for (int j = 0; j < i; j++)
            {
               
              //  If arr[i] is greater than arr[j] and the length
              // of lis[j] is greater than or equal to the length of lis[i] – 1,
              // then we update lis[i] to be lis[j] followed by arr[i].
                if (arr[j] < arr[i] && lis[j].Count > lis[i].Count - 1)
                {
                    lis[i] = new List<int>(lis[j]);
                    lis[i].Add(arr[i]);
                }
            }
        }
 
     // Intialize a maxSum by
    // a small number
        int maxSum = 0;
        List<int> maxIndex = new List<int>();
        for (int i = 0; i < n; i++)
        {
            int sum = lis[i].Sum();
            if (sum > maxSum)
            {
                maxSum = sum;
                maxIndex = new List<int>(lis[i]);
            }
        }
 
        //iterate through each element of the original string s and
          // add it to the output string ans if its corresponding element
        // in the arr vector is present in the maxIndex vector.
        string ans = "";
        for (int i = 0; i < n; i++)
        {
            if (maxIndex.Contains(arr[i]))
            {
                ans += s[i];
            }
        }
        return ans;
    }
 
  // Driver code
    static void Main(string[] args)
    {
        string s = "pqrstuv";
        List<int> arr = new List<int> { 2, 3, 1, 4, 6, 5, 8 };
 
      // Function call
        string heaviestIS = HeaviestIncreasingSubsequence(s, arr);
        Console.WriteLine(heaviestIS);
    }
}


Javascript




// Functiont to heaviest
// subsequence string
function heaviestIncreasingSubsequence(s, arr) {
    let n = s.length;
    let lis = [];
    for (let i = 0; i < n; i++) {
        lis[i] = [arr[i]];
        for (let j = 0; j < i; j++) {
         
                //  If arr[i] is greater than arr[j] and the length
              // of lis[j] is greater than or equal to the length of lis[i] – 1,
              // then we update lis[i] to be lis[j] followed by arr[i].
            if (arr[j] < arr[i] && lis[j].length > lis[i].length - 1) {
                lis[i] = [...lis[j]];
                lis[i].push(arr[i]);
            }
        }
    }
     
    // Intialize a maxSum by
    // a small number
    let maxSum = 0;
    let maxIndex = [];
    for (let i = 0; i < n; i++) {
        let sum = lis[i].reduce((acc, val) => acc + val, 0);
        if (sum > maxSum) {
            maxSum = sum;
            maxIndex = [...lis[i]];
        }
    }
     
    //iterate through each element of the original string s and
    // add it to the output string ans if its corresponding element
    // in the arr vector is present in the maxIndex vector.
    let ans = "";
    for (let i = 0; i < n; i++) {
        if (maxIndex.includes(arr[i])) {
            ans += s[i];
        }
    }
    return ans;
}
 
let s = "pqrstuv";
let arr = [2, 3, 1, 4, 6, 5, 8];
 
// Function call
let heaviestIS = heaviestIncreasingSubsequence(s, arr);
console.log(heaviestIS);


Output

pqstv




Time Complexity: O(n^2)
Auxiliary Space: O(n^2)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads