Find the maximum sum on the basis of the given Binary String
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++
// 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
// 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)); } } |
Python3
# 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#
// 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
// 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
Please Login to comment...