Given a binary string str and an array of positive integers profit[]. The task is to find the maximum possible sum if we are allowed to use only the elements whose corresponding index has a ‘1’ in the binary string and any “01” substring can be changed to a “10” substring.
Examples:
Input: str = “01110”, profit[] = {10, 5, 8, 9, 6}
Output: 27
Explanation: Initially, the profit is 5 + 8 + 9 = 22. After one operation, the string can be made “10110” which will give the sum as 10 + 8 + 9 = 27.Input: str = “011011”, profit[] = {20, 10, 9, 30, 20, 9}
Output: 80
Approach: This can be solved using the following idea.
The problem can be solved using a greedy approach. We can set any ‘0’ bit if there is at least one ‘1’ after it in the string. Consider, there are X 1s in the string. So the optimal idea is to select top X elements from the array such that they all lie before the last ‘1’ of the binary string.
We can implement this idea using a max heap (priority queue).
Follow the steps mentioned below to solve the problem:
- Initialize a priority queue (say pq) which will implement a max heap.
- Iterate over the binary string and for each index:
- Enter the corresponding value of the array in the priority queue.
- If the character in the binary string is ‘1’ pop the topmost element and add it to the answer.
- Return the answer after the iteration is over.
Below is the implementation of the above approach:
// C++ code for the above approach #include <bits/stdc++.h> using namespace std;
// Function to find the maximum profit int findmax_profit( int profit[], string str, int n)
{ // Initialize a priority queue to implement the max heap
priority_queue< int > pq;
int res = 0;
// Loop to find the maximum possible sum
for ( int i = 0; i < n; i++) {
// Insert the array value in priority queue
pq.push(profit[i]);
// If the string value is '1'
// pop the highest possible value
// from priority queue
if (str[i] == '1' ) {
res += pq.top();
pq.pop();
}
}
// Return the res
return res;
} // Driver code int main()
{ // Test case 1
int profit[] = { 12, 10, 5, 8, 9, 6 };
string str = "001110" ;
int N = sizeof (profit) / sizeof (profit[0]);
cout << findmax_profit(profit, str, N) << endl;
// Test case 2
int profit1[] = { 10, 5, 8, 9, 6 };
string str1 = "01110" ;
N = sizeof (profit1) / sizeof (profit1[0]);
cout << findmax_profit(profit1, str1, N) << endl;
// Test case 3
int profit2[] = { 20, 10, 9, 30, 20, 9 };
string str2 = "011011" ;
N = sizeof (profit2) / sizeof (profit2[0]);
cout << findmax_profit(profit2, str2, N);
return 0;
} |
// Java code for the above approach import java.io.*;
import java.util.*;
class GFG {
// Function to find the maximum profit
static int findmax_profit( int [] profit, String str,
int n)
{
// Initialize a priority queue to implement the max
// heap
PriorityQueue<Integer> pq
= new PriorityQueue<Integer>(
Collections.reverseOrder());
int res = 0 ;
// Loop to find the maximum possible sum
for ( int i = 0 ; i < n; i++) {
// Insert the array value in priority queue
pq.add(profit[i]);
// If the string value is '1'
// pop the highest possible value
// from priority queue
if (str.charAt(i) == '1' ) {
res += pq.peek();
pq.poll();
}
}
// Return the res
return res;
}
public static void main(String[] args)
{
// Test case 1
int [] profit = { 12 , 10 , 5 , 8 , 9 , 6 };
String str = "001110" ;
int N = profit.length;
System.out.println(findmax_profit(profit, str, N));
// Test case 2
int [] profit1 = { 10 , 5 , 8 , 9 , 6 };
String str1 = "01110" ;
N = profit1.length;
System.out.println(
findmax_profit(profit1, str1, N));
// Test case 3
int [] profit2 = { 20 , 10 , 9 , 30 , 20 , 9 };
String str2 = "011011" ;
N = profit2.length;
System.out.println(
findmax_profit(profit2, str2, N));
}
} |
# Python code for the above approach import bisect
# Function to find the maximum profit def findmax_profit(profit, str ,n):
# Initialize a priority queue to implement the max heap
pq = []
res = 0
# Loop to find the maximum possible sum
for i in range (n):
# Insert the array value in priority queue
bisect.insort(pq,profit[i])
# If the string value is '1'
# pop the highest possible value
# from priority queue
if ( str [i] = = '1' ):
res + = pq[ - 1 ]
pq.pop( - 1 )
# Return the res
return res
# Driver code # Test case 1 profit = [ 12 , 10 , 5 , 8 , 9 , 6 ]
str = "001110"
N = len (profit)
print (findmax_profit(profit, str ,N))
# Test case 2 profit1 = [ 10 , 5 , 8 , 9 , 6 ]
str1 = "01110"
N = len (profit1)
print (findmax_profit(profit1,str1,N))
# Test case 3 profit2 = [ 20 , 10 , 9 , 30 , 20 , 9 ]
str2 = "011011"
N = len (profit2)
print (findmax_profit(profit2,str2,N))
# This code is contributed by Pushpesh Raj. |
// C# code for the above approach using System;
using System.Collections.Generic;
namespace MaxProfit
{ class Program
{
// Function to find the maximum profit
static int FindMaxProfit( int [] profit, string str)
{
// Initialize a priority queue to implement the max heap
int n = profit.Length;
int res = 0;
var pq = new SortedSet< int >(Comparer< int >.Create((a, b) => b.CompareTo(a)));
for ( int i = 0; i < n; i++)
{
// Insert the array value in priority queue
pq.Add(profit[i]);
// If the string value is '1'
// pop the highest possible value
// from priority queue
if (str[i] == '1' )
{
res += pq.Min;
pq.Remove(pq.Min);
}
}
// Return the res
return res;
}
// Driver code
static void Main( string [] args)
{
// Test case 1
int [] profit = { 12, 10, 5, 8, 9, 6 };
string str = "001110" ;
Console.WriteLine(FindMaxProfit(profit, str));
// Test case 2
int [] profit1 = { 10, 5, 8, 9, 6 };
string str1 = "01110" ;
Console.WriteLine(FindMaxProfit(profit1, str1));
// Test case 3
int [] profit2 = { 20, 10, 9, 30, 20, 9 };
string str2 = "011011" ;
Console.WriteLine(FindMaxProfit(profit2, str2));
}
}
} // This code is contributed by Rutik Bhosale.. |
// JavaScript code for the above approach class MaxHeap { constructor() {
this .values = [];
}
// index of the parent node
parent(index) {
return Math.floor((index - 1) / 2);
}
// index of the left child node
leftChild(index) {
return (index * 2) + 1;
}
// index of the right child node
rightChild(index) {
return (index * 2) + 2;
}
// returns true if index is of a node that has no children
isLeaf(index) {
return (
index >= Math.floor( this .values.length / 2) && index <= this .values.length - 1
)
}
// swap using ES6 destructuring
swap(index1, index2) {
[ this .values[index1], this .values[index2]] = [ this .values[index2], this .values[index1]];
}
heapifyDown(index) {
// if the node at index has children
if (! this .isLeaf(index)) {
// get indices of children
let leftChildIndex = this .leftChild(index),
rightChildIndex = this .rightChild(index),
// start out largest index at parent index
largestIndex = index;
// if the left child > parent
if ( this .values[leftChildIndex] > this .values[largestIndex]) {
// reassign largest index to left child index
largestIndex = leftChildIndex;
}
// if the right child > element at largest index (either parent or left child)
if ( this .values[rightChildIndex] >= this .values[largestIndex]) {
// reassign largest index to right child index
largestIndex = rightChildIndex;
}
// if the largest index is not the parent index
if (largestIndex !== index) {
// swap
this .swap(index, largestIndex);
// recursively move down the heap
this .heapifyDown(largestIndex);
}
}
}
heapifyUp(index) {
let currentIndex = index,
parentIndex = this .parent(currentIndex);
// while we haven't reached the root node and the current element is greater than its parent node
while (currentIndex > 0 && this .values[currentIndex] > this .values[parentIndex]) {
// swap
this .swap(currentIndex, parentIndex);
// move up the binary heap
currentIndex = parentIndex;
parentIndex = this .parent(parentIndex);
}
}
add(element) {
// add element to the end of the heap
this .values.push(element);
// move element up until it's in the correct position
this .heapifyUp( this .values.length - 1);
}
// returns value of max without removing
peek() {
return this .values[0];
}
// removes and returns max element
extractMax() {
if ( this .values.length < 1) return 'heap is empty' ;
// get max and last element
const max = this .values[0];
const end = this .values.pop();
// reassign first element to the last element
this .values[0] = end;
// heapify down until element is back in its correct position
this .heapifyDown(0);
// return the max
return max;
}
buildHeap(array) {
this .values = array;
// since leaves start at floor(nodes / 2) index, we work from the leaves up the heap
for (let i = Math.floor( this .values.length / 2); i >= 0; i--){
this .heapifyDown(i);
}
}
/*print() {
let i = 0;
while (!this.isLeaf(i)) {
console.log("PARENT:", this.values[i]);
console.log("LEFT CHILD:", this.values[this.leftChild(i)]);
console.log("RIGHT CHILD:", this.values[this.rightChild(i)]);
i++;
}
}*/
} // Function to find the maximum profit function findmax_profit(profit, str, n)
{ // Initialize a priority queue to implement the max heap
let pq = new MaxHeap();
let res = 0;
// Loop to find the maximum possible sum
for (let i = 0; i < n; i++) {
// Insert the array value in priority queue
pq.add(profit[i]);
// If the string value is '1'
// pop the highest possible value
// from priority queue
if (str[i] == '1' ) {
res += pq.peek();
pq.extractMax();
}
}
// Return the res
return res;
} // Driver code // Test case 1
let profit = [ 12, 10, 5, 8, 9, 6 ];
let str = "001110" ;
let N = profit.length;
console.log(findmax_profit(profit, str, N));
// Test case 2
let profit1 = [ 10, 5, 8, 9, 6 ];
let str1 = "01110" ;
N = profit.length;
console.log(findmax_profit(profit1, str1, N));
// Test case 3
let profit2 = [ 20, 10, 9, 30, 20, 9 ];
let str2 = "011011" ;
N = profit.length;
console.log(findmax_profit(profit2, str2, N));
// This code is contributed by poojaagarwal2. |
31 27 80
Time Complexity: O(N * logN) where N is the length of the array.
Auxiliary Space: O(N), since we are using a priority queue data structure and in the worst case all elements of the array will be inserted in the priority queue thus taking up space equal to the size of the array
Related Articles:
- Introduction to Arrays – Data Structures and Algorithms Tutorials
- Introduction to Heap – Data Structures and Algorithms Tutorials
- k largest(or smallest) elements in an array