Maximum score possible by removing substrings made up of single distinct character
Last Updated :
06 Oct, 2021
Given a binary string S and an array A[], both of size N, the task is to find the maximum score possible by removing substrings of any length, say K, consisting of the same characters, and adding A[K] to the score.
Examples:
Input: S = “abb”, A = [1, 3, 1]
Output: 4
Explanation:
Initially, score = 0 and S=”abb”
Remove the substring {S[1], .. S[2]}, of length 2, and add A[2] to score. Therefore, S modifies to “a”. Score = 3.
Remove the substring {S[0]}, of length 1, and add A[1] to score. Therefore, S modifies to “”. Score = 4.
Input: S = “abb”, A = [2, 3, 1]
Output: 6
Explanation:
Initially, score = 0 and S=”abb”.
Remove the substring {S[2]}, of length 1, and add A[1] to score. Therefore, S modifies to “ab”. Score = 1
Remove the substring {S[1]}, of length 1, and add A[1] to score. Therefore, S modifies to “a”. Score = 4
Remove the substring {S[0]}, of length 1, and add A[1] to score. Therefore, S modifies to “”. Score = 6
Naive Approach: The simplest idea is to solve this problem is to use Recursion. Iterate over the characters of the string. If a substring consisting only of one distinct character is encountered, then proceed with either to continue the search or to remove the substring and recursively call the function for the remaining string.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool isUnique(string s)
{
set< char > Set;
for ( char c : s)
{
Set.insert(c);
}
return Set.size() == 1;
}
int maxScore(string s, int a[])
{
int n = s.length();
if (n == 0)
return 0;
if (n == 1)
return a[0];
int mx = -1;
for ( int i = 0; i < n; i++)
{
for ( int j = i; j < n; j++)
{
string sub = s.substr(i, j + 1);
if (isUnique(sub))
mx = max(mx, a[sub.length() - 1] + maxScore(s.substr(0, i) + s.substr(j + 1), a));
}
}
return mx;
}
int main()
{
string s = "011" ;
int a[] = { 1, 3, 1 };
cout << maxScore(s, a)-1;
return 0;
}
|
Java
import java.util.*;
class GFG
{
static boolean isUnique(String s)
{
HashSet<Character> set = new HashSet<>();
for ( char c : s.toCharArray())
set.add(c);
return set.size() == 1 ;
}
static int maxScore(String s, int [] a)
{
int n = s.length();
if (n == 0 )
return 0 ;
if (n == 1 )
return a[ 0 ];
int mx = - 1 ;
for ( int i = 0 ; i < n; i++)
{
for ( int j = i; j < n; j++)
{
String sub = s.substring(i, j + 1 );
if (isUnique(sub))
mx = Math.max(
mx,
a[sub.length() - 1 ]
+ maxScore(
s.substring( 0 , i)
+ s.substring(j + 1 ),
a));
}
}
return mx;
}
public static void main(String args[])
{
String s = "011" ;
int a[] = { 1 , 3 , 1 };
System.out.print(maxScore(s, a));
}
}
|
Python3
def isUnique(s):
return True if len ( set (s)) = = 1 else False
def maxScore(s, a):
n = len (s)
if n = = 0 :
return 0
if n = = 1 :
return a[ 0 ]
mx = - 1
for i in range (n):
for j in range (i, n):
sub = s[i:j + 1 ]
if isUnique(sub):
mx = max (mx, a[ len (sub) - 1 ]
+ maxScore(s[:i] + s[j + 1 :], a))
return mx
if __name__ = = "__main__" :
s = "011"
a = [ 1 , 3 , 1 ]
print (maxScore(s, a))
|
C#
using System;
using System.Collections.Generic;
class GFG {
static bool isUnique( string s)
{
HashSet< char > set = new HashSet< char >();
foreach ( char c in s)
set .Add(c);
return set .Count == 1;
}
static int maxScore( string s, int [] a)
{
int n = s.Length;
if (n == 0)
return 0;
if (n == 1)
return a[0];
int mx = -1;
for ( int i = 0; i < n; i++)
{
for ( int j = i; j < n; j++)
{
string sub = s.Substring(i, j + 1 - i);
if (isUnique(sub))
mx = Math.Max(
mx,
a[sub.Length - 1]
+ maxScore(
s.Substring(0, i)
+ s.Substring(j + 1),
a));
}
}
return mx;
}
static void Main() {
string s = "011" ;
int [] a = { 1, 3, 1 };
Console.Write(maxScore(s, a));
}
}
|
Javascript
<script>
function isUnique( s)
{
var set = new Set();
for (let i = 0 ; i< s.length ; i++)
{
set.add(s[i]);
}
return set.size == 1;
}
function maxScore( s, a)
{
let n = s.length;
if (n == 0)
return 0;
if (n == 1)
return a[0];
let mx = -1;
for (let i = 0; i < n; i++)
{
for (let j = i; j < n; j++)
{
let sub = s.substring(i, j + 1);
if (isUnique(sub))
mx = Math.max(
mx,
a[sub.length - 1]
+ maxScore(
s.substring(0, i)
+ s.substring(j + 1),
a));
}
}
return mx;
}
let s = "011" ;
let a = [ 1, 3, 1 ];
document.write(maxScore(s, a));
</script>
|
Time Complexity: O(N2)
Auxiliary Space: O(1)
Efficient Approach: To optimize the above approach, the idea is to use Memoization to store the result of the recursive calls and use Two pointer technique to store the substring consisting only of 1 distinct character.
Follow the steps below to solve the problem:
- Declare a recursive function that takes the string as the input to find the required result.
- Initialize an array, say dp[] to memorize the results.
- If the value is already stored in the array dp[], return the result.
- Otherwise, perform the following steps:
- Considering the base case if the size of the string is 0, return 0. If it is equal to 1, return A[1].
- Initialize a variable, say res, to store the result of the current function call.
- Initialize two pointers, say head and tail, denoting the starting and ending indices of the substring.
- Generate substrings satisfying the given condition, and for each substring, recursively call the function for the remaining string. Store the maximum score in res.
- Store the result in the dp[] array and return it.
- Print the value returned by the function as the result.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
map<string, int > dp;
int maxScore(string s, vector< int > a)
{
if (dp.find(s) != dp.end())
return dp[s];
int n = s.size();
if (n == 0)
return 0;
if (n == 1)
return a[0];
int head = 0;
int mx = -1;
while (head < n)
{
int tail = head;
while (tail < n)
{
if (s[tail] != s[head])
{
head = tail;
break ;
}
string sub = s.substr(head, tail + 1);
mx = max(mx, a[sub.size() - 1] +
maxScore(s.substr(0, head) +
s.substr(tail + 1,s.size()), a));
tail += 1;
}
if (tail == n)
break ;
}
dp[s] = mx;
return mx;
}
int main()
{
string s = "abb" ;
vector< int > a = {1, 3, 1};
cout<<(maxScore(s, a)-1);
}
|
Java
import java.util.*;
class GFG{
static Map<String, Integer> dp = new HashMap<>();
static int maxScore(String s, int [] a)
{
if (dp.containsKey(s))
return dp.get(s);
int n = s.length();
if (n == 0 )
return 0 ;
if (n == 1 )
return a[ 0 ];
int head = 0 ;
int mx = - 1 ;
while (head < n)
{
int tail = head;
while (tail < n)
{
if (s.charAt(tail) != s.charAt(head))
{
head = tail;
break ;
}
String sub = s.substring(head, tail + 1 );
mx = Math.max(
mx, a[sub.length() - 1 ] +
maxScore(s.substring( 0 , head) +
s.substring(tail + 1 , s.length()), a));
tail += 1 ;
}
if (tail == n)
break ;
}
dp.put(s, mx);
return mx;
}
public static void main(String[] args)
{
String s = "abb" ;
int [] a = { 1 , 3 , 1 };
System.out.println((maxScore(s, a)));
}
}
|
Python3
dp = dict ()
def maxScore(s, a):
if s in dp:
return dp[s]
n = len (s)
if n = = 0 :
return 0
if n = = 1 :
return a[ 0 ]
head = 0
mx = - 1
while head < n:
tail = head
while tail < n:
if s[tail] ! = s[head]:
head = tail
break
sub = s[head:tail + 1 ]
mx = max (mx, a[ len (sub) - 1 ]
+ maxScore(s[:head] + s[tail + 1 :], a))
tail + = 1
if tail = = n:
break
dp[s] = mx
return mx
if __name__ = = "__main__" :
s = "abb"
a = [ 1 , 3 , 1 ]
print (maxScore(s, a))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static Dictionary< string ,
int > dp = new Dictionary< string ,
int >();
static int maxScore( string s, int [] a)
{
if (dp.ContainsKey(s))
return dp[s];
int n = s.Length;
if (n == 0)
return 0;
if (n == 1)
return a[0];
int head = 0;
int mx = -1;
while (head < n)
{
int tail = head;
while (tail < n)
{
if (s[tail] != s[head])
{
head = tail;
break ;
}
string sub = s.Substring(head, tail + 1-head);
mx = Math.Max(
mx, a[sub.Length - 1] +
maxScore(s.Substring(0, head) +
s.Substring(tail + 1, s.Length-tail - 1), a));
tail += 1;
}
if (tail == n)
break ;
}
dp.Add(s, mx);
return mx;
}
static public void Main()
{
string s = "abb" ;
int [] a = { 1, 3, 1 };
Console.WriteLine((maxScore(s, a)));
}
}
|
Javascript
<script>
let dp = new Map();
function maxScore(s, a)
{
if (dp.has(s))
return dp.get(s);
let n = s.length;
if (n == 0)
return 0;
if (n == 1)
return a[0];
let head = 0;
let mx = -1;
while (head < n)
{
let tail = head;
while (tail < n)
{
if (s[tail] != s[head])
{
head = tail;
break ;
}
let sub = s.substring(head, head + tail + 1);
mx = Math.max(
mx, a[sub.length - 1] +
maxScore(s.substring(0, head) +
s.substring(tail + 1, tail + 1 + s.length), a));
tail += 1;
}
if (tail == n)
break ;
}
dp.set(s, mx);
return mx;
}
let s = "abb" ;
let a = [ 1, 3, 1 ];
document.write((maxScore(s, a))-1);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...