Open In App

Find heaviest increasing Subsequence with maximum sum in a String

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:

Below is the implementation of the above approach:




// 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;
}




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);
    }
}




# 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)




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);
    }
}




// 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)


Article Tags :