Skip to content
Related Articles

Related Articles

Improve Article

Find value after N operations to remove N characters of string S with given constraints

  • Last Updated : 13 Sep, 2021

Given a string S of Size N. Initially, the value of count is 0. The task is to find the value of count after N operations to remove all the N characters of the given string S where each operation is:

  • In each operation, select alphabetically the smallest character in the string S and remove that character from S and add its index to count.
  • If multiple characters are present then remove the character having the smallest index.

Note: Consider string as 1-based indexing.

Examples:

Input: N = 5, S = “abcab” 
Output:
Explanation: 
Remove character ‘a’ then string becomes “bcab” and the count = 1. 
Remove character ‘a’ then string becomes “bcb” and the count = 1 + 3 = 4. 
Remove character ‘b’ then string becomes “cb” and the count = 4 + 1 = 5. 
Remove character ‘b’ then string becomes “c” and the count = 5 + 2 = 7. 
Remove character ‘c’ then string becomes “” and the count = 7 + 1 = 8.

Input: N = 5 S = “aabbc” 
Output:
Explanation: 
The value after 5 operations to remove all the 5 characters of String aabbc is 5.



Naive Approach: The idea is to check if the string is empty or not. If it is not empty then following are the steps to solve the problem:

  • Find the first occurrence of the smallest alphabets in the current string, let’s say ind and remove it from the string.
  • Increase the count by ind + 1.
  • Repeat the above step until the string becomes empty.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <iostream>
#include <string>
using namespace std;
 
// Function to find the value after
// N operations to remove all the N
// characters of string S
void charactersCount(string str, int n)
{
    int count = 0;
 
    // Iterate till N
    while (n > 0) {
 
        char cur = str[0];
        int ind = 0;
 
        for (int j = 1; j < n; j++) {
 
            if (str[j] < cur) {
                cur = str[j];
                ind = j;
            }
        }
 
        // Remove character at ind and
        // decrease n(size of string)
        str.erase(str.begin() + ind);
        n--;
 
        // Increase count by ind+1
        count += ind + 1;
    }
    cout << count << endl;
}
 
// Driver Code
int main()
{
    // Given string str
    string str = "aabbc";
    int n = 5;
 
    // Function call
    charactersCount(str, n);
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to find the value after
// N operations to remove all the N
// characters of String S
static void charactersCount(String str, int n)
{
    int count = 0;
 
    // Iterate till N
    while (n > 0)
    {
        char cur = str.charAt(0);
        int ind = 0;
 
        for(int j = 1; j < n; j++)
        {
            if (str.charAt(j) < cur)
            {
                cur = str.charAt(j);
                ind = j;
            }
        }
 
        // Remove character at ind and
        // decrease n(size of String)
        str = str.substring(0, ind) +
              str.substring(ind + 1);
        n--;
 
        // Increase count by ind+1
        count += ind + 1;
    }
    System.out.print(count + "\n");
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given String str
    String str = "aabbc";
     
    int n = 5;
 
    // Function call
    charactersCount(str, n);
}
}
 
// This code is contributed by amal kumar choubey


Python3




# Python3 program for the above approach
 
# Function to find the value after
# N operations to remove all the N
# characters of String S
def charactersCount(str, n):
     
    count = 0;
 
    # Iterate till N
    while (n > 0):
        cur = str[0];
        ind = 0;
 
        for j in range(1, n):
            if (str[j] < cur):
                cur = str[j];
                ind = j;
 
        # Remove character at ind and
        # decrease n(size of String)
        str = str[0 : ind] + str[ind + 1:];
        n -= 1;
 
        # Increase count by ind+1
        count += ind + 1;
 
    print(count);
 
# Driver Code
if __name__ == '__main__':
     
    # Given String str
    str = "aabbc";
 
    n = 5;
 
    # Function call
    charactersCount(str, n);
 
# This code is contributed by Amit Katiyar


C#




// C# program for the above approach
using System;
class GFG{
 
// Function to find the value after
// N operations to remove all the N
// characters of String S
static void charactersCount(String str, int n)
{
    int count = 0;
 
    // Iterate till N
    while (n > 0)
    {
        char cur = str[0];
        int ind = 0;
 
        for(int j = 1; j < n; j++)
        {
            if (str[j] < cur)
            {
                cur = str[j];
                ind = j;
            }
        }
 
        // Remove character at ind and
        // decrease n(size of String)
        str = str.Substring(0, ind) +
              str.Substring(ind + 1);
        n--;
 
        // Increase count by ind+1
        count += ind + 1;
    }
    Console.Write(count + "\n");
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Given String str
    String str = "aabbc";
     
    int n = 5;
 
    // Function call
    charactersCount(str, n);
}
}
 
// This code is contributed by gauravrajput1


Javascript




<script>
    // Javascript program for the above approach
     
    // Function to find the value after
    // N operations to remove all the N
    // characters of String S
    function charactersCount(str, n)
    {
        let count = 0;
 
        // Iterate till N
        while (n > 0)
        {
            let cur = str[0].charCodeAt();
            let ind = 0;
 
            for(let j = 1; j < n; j++)
            {
                if (str[j].charCodeAt() < cur)
                {
                    cur = str[j].charCodeAt();
                    ind = j;
                }
            }
 
            // Remove character at ind and
            // decrease n(size of String)
            str = str.substring(0, ind) +
                  str.substring(ind + 1);
            n--;
 
            // Increase count by ind+1
            count += ind + 1;
        }
        document.write(count + "</br>");
    }
     
    // Given String str
    let str = "aabbc";
      
    let n = 5;
  
    // Function call
    charactersCount(str, n);
 
// This code is contributed by divyeshrabadiya07.
</script>


Output: 

5

 

Time Complexity: O(N2)
Auxiliary Space: O(1)

Efficient Approach: This problem can be solved using the concept of Binary Index Tree or Fenwick Tree. Below are the steps:

  • Initially, Store the values of indices of all the characters/alphabet in increasing order.
  • Start with the smallest alphabet ‘a’ and remove all ‘a’s in the order of there occurrence. After removing, select the next alphabet ‘b’, and repeat this step until all alphabets are removed.
  • Removing the character means that its corresponding value in the array is changed to 0, indicating that it is removed.
  • Before removing, find the position of the character in the string using the sum() method in Fenwick Tree and add the position value to the count.
  • After removing all the characters in the string, the value of count is obtained.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Structure of Fenwick tree
struct FenwickTree {
 
    // Binary indexed tree
    vector<int> bit;
 
    // bit[0] is not involved
    int n;
 
    // Constructor
    FenwickTree(int n)
    {
        this->n = n + 1;
        bit = vector<int>(n, 0);
    }
 
    // Constructor
    FenwickTree(vector<int> a)
        : FenwickTree(a.size())
    {
        for (size_t i = 0; i < a.size(); i++)
            add(i, a[i]);
    }
 
    // Sum of arr[0] + arr[1] + ...
    // + arr[idx] where arr is array
    int sum(int idx)
    {
        int ret = 0;
 
        // Index in BITree[] is 1 more
        // than the index in arr[]
        idx = idx + 1;
 
        // Traverse the ancestors of
        // BITree[index]
        while (idx > 0) {
 
            // Add current element
            // of BITree to sum
            ret += bit[idx];
 
            // Move index to parent
            // node in getSum View
            idx -= idx & (-idx);
        }
 
        // Return the result
        return ret;
    }
 
    // Function for adding arr[idx]
    // is equals to arr[idx] + val
    void add(int idx, int val)
    {
 
        // Val is nothing but "DELTA"
        // index in BITree[] is 1
        // more than the index in arr[]
        idx = idx + 1;
 
        // Traverse all ancestors
        // and add 'val'
        while (idx <= n) {
 
            // Add 'val' to current
            // node of BI Tree
            bit[idx] += val;
 
            // Update index to that
            // of parent in update View
            idx += idx & (-idx);
        }
    }
 
    // Update the index
    void update(int idx, int val)
    {
        add(idx, val - valat(idx));
    }
 
    // Perform the sum arr[l] + arr[l+1]
    // + ... + arr[r]
    int sum(int l, int r)
    {
        return sum(r) - sum(l - 1);
    }
 
    int valat(int i)
    {
        return sum(i, i);
    }
 
    void clr(int sz)
    {
        bit.clear();
        n = sz + 1;
        bit.resize(n + 1, 0);
 
        // Initially mark all
        // are present (i.e. 1)
        for (int i = 0; i < n; i++)
            add(i, 1);
    }
};
 
// Function to count the characters
void charactersCount(string str, int n)
{
    int i, count = 0;
 
    // Store the values of indexes
    // for each alphabet
    vector<vector<int> > mp
        = vector<vector<int> >(26,
                               vector<int>());
 
    // Create FenwickTree of size n
    FenwickTree ft = FenwickTree(n);
    ft.clr(n);
 
    // Initially no indexes are
    // stored for each character
    for (i = 0; i < 26; i++)
        mp[i].clear();
 
    i = 0;
    for (char ch : str) {
 
        // Push 'i' to mp[ch]
        mp[ch - 'a'].push_back(i);
        i++;
    }
 
    // Start with smallest character
    // and move towards larger character
    // i.e., from 'a' to 'z' (0 to 25)
    for (i = 0; i < 26; i++) {
 
        // index(ind) of current character
        // corres to i are obtained
        // in increasing order
        for (int ind : mp[i]) {
 
            // Find the number of characters
            // currently present before
            // ind using ft.sum(ind)
            count += ft.sum(ind);
 
            // Mark the corresponding
            // ind as removed and
            // make value at ind as 0
            ft.update(ind, 0);
        }
    }
 
    // Print the value of count
    cout << count << endl;
}
 
// Driver Code
int main()
{
    // Given string str
    string str = "aabbc";
 
    int n = 5;
 
    // Function call
    charactersCount(str, n);
    return 0;
}


Java




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Structure of Fenwick tree
struct FenwickTree {
 
    // Binary indexed tree
    vector<int> bit;
 
    // bit[0] is not involved
    int n;
 
    // Constructor
    FenwickTree(int n)
    {
        this->n = n + 1;
        bit = vector<int>(n, 0);
    }
 
    // Constructor
    FenwickTree(vector<int> a)
        : FenwickTree(a.size())
    {
        for (size_t i = 0; i < a.size(); i++)
            add(i, a[i]);
    }
 
    // Sum of arr[0] + arr[1] + ...
    // + arr[idx] where arr is array
    int sum(int idx)
    {
        int ret = 0;
 
        // Index in BITree[] is 1 more
        // than the index in arr[]
        idx = idx + 1;
 
        // Traverse the ancestors of
        // BITree[index]
        while (idx > 0) {
 
            // Add current element
            // of BITree to sum
            ret += bit[idx];
 
            // Move index to parent
            // node in getSum View
            idx -= idx & (-idx);
        }
 
        // Return the result
        return ret;
    }
 
    // Function for adding arr[idx]
    // is equals to arr[idx] + val
    void add(int idx, int val)
    {
 
        // Val is nothing but "DELTA"
        // index in BITree[] is 1
        // more than the index in arr[]
        idx = idx + 1;
 
        // Traverse all ancestors
        // and add 'val'
        while (idx <= n) {
 
            // Add 'val' to current
            // node of BI Tree
            bit[idx] += val;
 
            // Update index to that
            // of parent in update View
            idx += idx & (-idx);
        }
    }
 
    // Update the index
    void update(int idx, int val)
    {
        add(idx, val - valat(idx));
    }
 
    // Perform the sum arr[l] + arr[l+1]
    // + ... + arr[r]
    int sum(int l, int r)
    {
        return sum(r) - sum(l - 1);
    }
 
    int valat(int i)
    {
        return sum(i, i);
    }
 
    void clr(int sz)
    {
        bit.clear();
        n = sz + 1;
        bit.resize(n + 1, 0);
 
        // Initially mark all
        // are present (i.e. 1)
        for (int i = 0; i < n; i++)
            add(i, 1);
    }
};
 
// Function to count the characters
void charactersCount(string str, int n)
{
    int i, count = 0;
 
    // Store the values of indexes
    // for each alphabet
    vector<vector<int> > mp
        = vector<vector<int> >(26,
                               vector<int>());
 
    // Create FenwickTree of size n
    FenwickTree ft = FenwickTree(n);
    ft.clr(n);
 
    // Initially no indexes are
    // stored for each character
    for (i = 0; i < 26; i++)
        mp[i].clear();
 
    i = 0;
    for (char ch : str) {
 
        // Push 'i' to mp[ch]
        mp[ch - 'a'].push_back(i);
        i++;
    }
 
    // Start with smallest character
    // and move towards larger character
    // i.e., from 'a' to 'z' (0 to 25)
    for (i = 0; i < 26; i++) {
 
        // index(ind) of current character
        // corres to i are obtained
        // in increasing order
        for (int ind : mp[i]) {
 
            // Find the number of character
            // currently present before
            // ind using ft.sum(ind)
            count += ft.sum(ind);
 
            // Mark the corresponding
            // ind as removed and
            // make value at ind as 0
            ft.update(ind, 0);
        }
    }
 
    // Print the value of count
    cout << count << endl;
}
 
// Driver Code
int main()
{
    // Given string str
    string str = "aabbc";
 
    int n = 5;
 
    // Function call
    charactersCount(str, n);
    return 0;
}


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
// Structure of Fenwick tree
public class FenwickTree
{
 
    // Binary indexed tree
    public int []bit;
 
    // bit[0] is not involved
    int n;
 
    // Constructor
    public FenwickTree(int n)
    {
        this.n = n + 1;
        bit = new int[n];
    }
 
    // Constructor
    public FenwickTree(List<int> a)
    {
        for(int i = 0; i < a.Count; i++)
            add(i, a[i]);
    }
 
    // Sum of arr[0] + arr[1] + ...
    // + arr[idx] where arr is array
    public int sum(int idx)
    {
        int ret = 0;
 
        // Index in BITree[] is 1 more
        // than the index in []arr
        idx = idx + 1;
 
        // Traverse the ancestors of
        // BITree[index]
        while (idx > 0)
        {
 
            // Add current element
            // of BITree to sum
            ret += bit[idx];
 
            // Move index to parent
            // node in getSum View
            idx -= idx & (-idx);
        }
 
        // Return the result
        return ret;
    }
 
    // Function for adding arr[idx]
    // is equals to arr[idx] + val
    public void add(int idx, int val)
    {
 
        // Val is nothing but "DELTA"
        // index in BITree[] is 1
        // more than the index in []arr
        idx = idx + 1;
 
        // Traverse all ancestors
        // and add 'val'
        while (idx <= n)
        {
 
            // Add 'val' to current
            // node of BI Tree
            bit[idx] += val;
 
            // Update index to that
            // of parent in update View
            idx += idx & (-idx);
        }
    }
 
    // Update the index
    public void update(int idx, int val)
    {
        add(idx, val - valat(idx));
    }
 
    // Perform the sum arr[l] + arr[l+1]
    // + ... + arr[r]
    public int sum(int l, int r)
    {
        return sum(r) - sum(l - 1);
    }
 
    public int valat(int i)
    {
        return sum(i, i);
    }
 
    public void clr(int sz)
    {
        n = sz + 1;
        bit = new int[n + 1];
 
        // Initially mark all
        // are present (i.e. 1)
        for(int i = 0; i < n; i++)
            add(i, 1);
    }
};
 
// Function to count the characters
static void charactersCount(String str, int n)
{
    int i, count = 0;
 
    // Store the values of indexes
    // for each alphabate
    List<int> []mp = new List<int>[26];
    for(i = 0; i < mp.Length; i++)
        mp[i] = new List<int>();
         
    // Create FenwickTree of size n
    FenwickTree ft = new FenwickTree(n);
    ft.clr(n);
 
    // Initially no indexes are
    // stored for each character
    for(i = 0; i < 26; i++)
        mp[i].Clear();
 
    i = 0;
    foreach(char ch in str.ToCharArray())
    {
 
        // Push 'i' to mp[ch]
        mp[ch - 'a'].Add(i);
        i++;
    }
 
    // Start with smallest character
    // and move towards larger character
    // i.e., from 'a' to 'z' (0 to 25)
    for(i = 0; i < 26; i++)
    {
         
        // index(ind) of current character
        // corres to i are obtained
        // in increasing order
        foreach(int ind in mp[i])
        {
             
            // Find the number of characters
            // currently present before
            // ind using ft.sum(ind)
            count += ft.sum(ind);
 
            // Mark the corresponding
            // ind as removed and
            // make value at ind as 0
            ft.update(ind, 0);
        }
    }
 
    // Print the value of count
    Console.Write(count + "\n");
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Given String str
    String str = "aabbc";
 
    int n = 5;
 
    // Function call
    charactersCount(str, n);
}
}
 
// This code is contributed by amal kumar choubey


Javascript




<script>
 
// JavaScript program for the above approach
 
// Structure of Fenwick tree
class FenwickTree
{
    constructor(n)
    {
        this.n = n + 1;
        this.bit = new Array(n);
    }
    _FenwickTree(a)
    {
        for(let i = 0; i < a.length; i++)
            this.add(i, a.get(i));
    }
     
    // Sum of arr[0] + arr[1] + ...
    // + arr[idx] where arr is array
    sum(idx)
    {
        let ret = 0;
  
        // Index in BITree[] is 1 more
        // than the index in arr[]
        idx = idx + 1;
  
        // Traverse the ancestors of
        // BITree[index]
        while (idx > 0)
        {
  
            // Add current element
            // of BITree to sum
            ret += this.bit[idx];
  
            // Move index to parent
            // node in getSum View
            idx -= idx & (-idx);
        }
  
        // Return the result
        return ret;
    }
     
    // Function for adding arr[idx]
    // is equals to arr[idx] + val
    add(idx,val)
    {
        // Val is nothing but "DELTA"
        // index in BITree[] is 1
        // more than the index in arr[]
        idx = idx + 1;
  
        // Traverse all ancestors
        // and add 'val'
        while (idx <= this.n)
        {
  
            // Add 'val' to current
            // node of BI Tree
            this.bit[idx] += val;
  
            // Update index to that
            // of parent in update View
            idx += idx & (-idx);
        }
    }
     
    // Update the index
    update(idx,val)
    {
        this.add(idx, val - this.valat(idx));
    }
     
    // Perform the sum arr[l] + arr[l+1]
    // + ... + arr[r]
    _sum(l,r)
    {
        return this.sum(r) - this._sum(l - 1);
    }
     
    valat(i)
    {
        return this.sum(i, i);
    }
     
    clr(sz)
    {
        this.n = sz + 1;
        this.bit = new Array(this.n + 1);
         for(let i=0;i<this.n+1;i++)
            this.bit[i]=0;
         
        // Initially mark all
        // are present (i.e. 1)
        for(let i = 0; i < n; i++)
            this.add(i, 1);
    }
}
 
// Function to count the characters
function charactersCount(str,n)
{
    let i, count = 0;
  
    // Store the values of indexes
    // for each alphabet
     
    let mp = new Array(26);
    for(i = 0; i < mp.length; i++)
        mp[i] = [];
          
    // Create FenwickTree of size n
    let ft = new FenwickTree(n);
    ft.clr(n);
  
    // Initially no indexes are
    // stored for each character
    for(i = 0; i < 26; i++)
        mp[i]=[];
  
    i = 0;
    for(let ch of str.split("").values())
    {
  
        // Push 'i' to mp[ch]
        mp[ch.charCodeAt(0) - 'a'.charCodeAt(0)].push(i);
        i++;
    }
  
    // Start with smallest character
    // and move towards larger character
    // i.e., from 'a' to 'z' (0 to 25)
    for(i = 0; i < 26; i++)
    {
  
        // index(ind) of current character
        // corres to i are obtained
        // in increasing order
        for(let ind of mp[i].values())
        {
  
            // Find the number of characters
            // currently present before
            // ind using ft.sum(ind)
            count += ft.sum(ind);
  
            // Mark the corresponding
            // ind as removed and
            // make value at ind as 0
            ft.update(ind, 0);
        }
    }
  
    // Print the value of count
    document.write(count + "<br>");
}
 
// Driver Code
// Given String str
let str = "aabbc";
 
let n = 5;
 
// Function call
charactersCount(str, n);
 
 
// This code is contributed by unknown2108
 
</script>


Output: 

5

 

Time Complexity: O(N*log(N))
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :