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++ 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); |
pqstv
Time Complexity: O(n^2)
Auxiliary Space: O(n^2)