Maximize sum by multiplying adjacent difference of Binary String with any digit
Last Updated :
20 Jan, 2023
Given a binary string S and a string of non-zero digits P of length N, the task is to maximize the sum using the given operations, which can be used as my times you can:
- You can choose a substring of length 2 or 3.
- Delete that substring after calculating the absolute difference of adjacent elements from left to right and take any single digit from the string P and multiply that with the absolute difference obtained by chosen substring.
Examples:
Input: N = 4, S = 1001, P = 6574
Output: 13
Explanation: For string S = 1001, choose a substring from index 1 to 2 as substring= 10. Absolute difference = |1 – 0| = 1 Multiply it with the digit 7 of string P = 7*1 = 7. Now chosen substring (10) is deleted from string (1001) and remaining string is = 01.
Then, choose a substring from index 1 to 2 as substring = 01. Absolute difference = |0-1| = 1, Multiply it with the 6 of string P = 6*1 = 6. Now substring is deleted and string S is empty, and total maximum sum that can obtain is 7+6 = 13.
Input: N = 4, S = 1111, P = 1221
Output: 2
Explanation: For, string S = 1111, choose a sub-array from index 1 to 3 as sub-array = 111. Absolute difference of first left two elements of chosen substring = |1-1| = 0, Now substring is = 01.(By replacing obtained abs. difference with first two elements).
Now, absolute difference of first left two elements of current sub-array (01) = |0-1| = 1. Total absolute difference for this substring is 1. Take digit 2 from P and multiply it with obtained absolute difference = 1*2= 2. Now delete this substring(111) from S(1111), Then remained S is = 1.
We cannot make any operations further, Because S has single element and have not any adjacent element. Therefore, Maximum sum that can obtain is = 2.
Approach: Implement the idea below to solve the problem:
The problem can be solved by using Stack data structure and greedy approach to choose a digit from string P for multiplication. For knowing the exact algorithm to solve the problem see the Algorithm section below.
Follow the steps to solve the problem:
- Initialize a Stack (say stk) and create a counter and sum variables.
- Make an ArrayList lets call it digits to store digits of string P and sort it.
- Run a loop from 1 to N and do
- If stk is empty or the top of stk = current_element, push the typecasted integer element in the stack.
- Else if top of stk is not the same as current_element, pop the peek element from stk and add (1*last element of digits) into sum variable also remove used digits from the list.
- Now it is possible that some element remained in the stack. Therefore, run a while loop till the stk has no element in it. Count the number of 1 remaining in the stk in the counter variable.
- Modify the counter variable’s value now with (counter/3). The reason is that 3 ones can make absolute difference as 1, same as the input 2 in the example above.
- Do the same, add (1*last element of digits ArrayList) into sum variable also remove used digits from the list, while counter is greater than 0.
- Print the value of the sum variable.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
int maxSum(string S, string P, int N)
{
vector< int > digits;
for ( int i = 0; i < P.length(); i++) {
digits.push_back(P[i] - 48);
}
sort(digits.begin(), digits.end());
int sum = 0;
stack< int > s;
for ( int i = 0; i < N; i++) {
string str1 = "" ;
str1 += S[i];
int typecasted_int = stoi(str1);
if (s.empty()) {
s.push(typecasted_int);
}
else if (s.top() == typecasted_int) {
s.push(typecasted_int);
}
else if (s.top() != typecasted_int) {
sum += digits.back();
digits.pop_back();
s.pop();
}
}
int counter = 0;
while (!s.empty()) {
if (s.top() == 1) {
counter++;
}
s.pop();
}
counter = counter / 3;
while (counter-- > 0) {
sum += digits.back();
digits.pop_back();
}
return sum;
}
int main()
{
string S = "1001" ;
string P = "6574" ;
int N = S.size();
cout << (maxSum(S, P, N));
}
|
Java
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG {
static long maxSum(String S, String P, int N)
{
ArrayList<Integer> digits = new ArrayList<>();
for ( int i = 0 ; i < P.length(); i++) {
digits.add(Integer.parseInt( "" + P.charAt(i)));
}
digits.sort( null );
long sum = 0 ;
Stack<Integer> s = new Stack<>();
for ( int i = 0 ; i < N; i++) {
String str1 = "" + S.charAt(i);
Integer typecasted_int = Integer.parseInt(str1);
if (s.isEmpty()) {
s.push(typecasted_int);
}
else if (s.peek() == typecasted_int) {
s.push(typecasted_int);
}
else if (s.peek() != typecasted_int) {
sum += 1
* ( int )(digits.get(digits.size()
- 1 ));
digits.remove(
digits.get(digits.size() - 1 ));
s.pop();
}
}
int counter = 0 ;
while (!s.isEmpty()) {
if (s.peek() == 1 ) {
counter++;
}
s.pop();
}
counter = counter / 3 ;
while (counter-- > 0 ) {
sum += 1 * digits.get(digits.size() - 1 );
digits.remove(digits.get(digits.size() - 1 ));
}
return sum;
}
public static void main(String args[])
{
String S = "1001" ;
String P = "6574" ;
int N = S.length();
System.out.println(maxSum(S, P, N));
}
}
|
Python
from typing import List
def maxSum(S, P, N):
digits = []
for i in range ( len (P)):
digits.append( int (P[i]))
digits.sort()
sum = 0
s = []
for i in range (N):
typecasted_int = int (S[i])
if not s:
s.append(typecasted_int)
elif s[ - 1 ] = = typecasted_int:
s.append(typecasted_int)
elif s[ - 1 ] ! = typecasted_int:
sum + = digits[ - 1 ]
del digits[ - 1 ]
del s[ - 1 ]
counter = 0
while s:
if s[ - 1 ] = = 1 :
counter + = 1
del s[ - 1 ]
counter = counter / / 3
while counter > 0 :
sum + = digits[ - 1 ]
del digits[ - 1 ]
counter - = 1
return sum
if __name__ = = "__main__" :
S = "1001"
P = "6574"
N = len (S)
print (maxSum(S, P, N))
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
public class GFG {
static long maxSum( string S, string P, int N)
{
ArrayList digits = new ArrayList();
for ( int i = 0; i < P.Length; i++) {
digits.Add( int .Parse( "" + P[i]));
}
digits.Sort( null );
long sum = 0;
Stack s = new Stack();
for ( int i = 0; i < N; i++) {
string str1 = "" + S[i];
int typecasted_int = int .Parse(str1);
if (s.Count == 0) {
s.Push(typecasted_int);
}
else if (( int )s.Peek() == typecasted_int) {
s.Push(typecasted_int);
}
else if (( int )s.Peek() != typecasted_int) {
sum += 1 * ( int )(digits[digits.Count - 1]);
digits.Remove(digits[digits.Count - 1]);
s.Pop();
}
}
int counter = 0;
while (s.Count != 0) {
if (( int )s.Peek() == 1) {
counter++;
}
s.Pop();
}
counter = counter / 3;
while (counter-- > 0) {
sum += 1 * ( int )digits[digits.Count - 1];
digits.Remove(digits[digits.Count - 1]);
}
return sum;
}
static public void Main()
{
string S = "1001" ;
string P = "6574" ;
int N = S.Length;
Console.WriteLine(maxSum(S, P, N));
}
}
|
Javascript
function maxSum(S, P, N) {
let digits = [];
for (let i = 0; i < P.length; i++) {
digits.push(parseInt( "" + P[i]));
}
digits.sort();
let sum = 0;
let s = [];
for (let i = 0; i < N; i++) {
let str1 = "" + S[i];
let typecasted_int = parseInt(str1);
if (s.length == 0) {
s.push(typecasted_int);
}
else if (s[S.length - 1] == typecasted_int) {
s.push(typecasted_int);
}
else if (s[s.length - 1] != typecasted_int) {
sum += 1
* parseInt(digits[digits.length - 1]);
digits.pop();
s.pop();
}
}
let counter = 0;
while (s.length != 0) {
if (s[S.length - 1] == 1) {
counter++;
}
s.pop();
}
counter = counter / 3;
while (counter-- > 0) {
sum += 1 * digits[digits.length - 1];
digits.pop();
}
return sum;
}
let S = "1001" ;
let P = "6574" ;
let N = S.length;
console.log(maxSum(S, P, N));
|
Time Complexity: O(N * log(N)), because sorting is performed.
Auxiliary Space: O(N), as list is required to store digits.
Share your thoughts in the comments
Please Login to comment...