# Sum of indices of Characters removed to obtain an Empty String based on given conditions

• Difficulty Level : Medium
• Last Updated : 17 Dec, 2021

Given a string str, consisting of lowercase English alphabets, the task is to calculate the sum of indices(1-based indexing) of the characters removed to obtain an empty string by the following operations:

• Remove the smallest alphabet in the string.
• For multiple occurrences of the smallest alphabet, remove the one present at the smallest index.
• After removal of each character, the indices of all characters on its right reduces by 1.

Examples:

Input: str = “aba”
Output:
Explanation:aba” -> “ba”, Sum = 1
“ba” -> “b”, Sum = 1 + 2 = 3
“b” -> “”, Sum = 3 + 1 = 4

Input: str = “geeksforgeeks”
Output: 41

Naive Approach:
Follow the steps below to solve the problem:

• Find the smallest character with minimum index.
• Delete that character from string and shift all the characters one index to the right.
• Repeat the above steps until the string is empty.

Time Complexity: O(N^2)
Auxiliary Space: O(N)

Efficient Approach: The above approach can be optimized using Segment Tree and Hashing. Follow the steps below to solve the problem:

• It can be observed that only the indices on the right of the deleted character are affected, that is, they need to be shifted by one position.
• Store the indices of the characters in a HashMap
• Process the characters in the HashMap.
• Find the number of elements which are left to the current index of the character, which are already deleted from the string, using Segment Tree.
• Extract the index of the deleted character and search over the range [0, index of extracted element] in the Segment Tree and find the count of indices in the range present in the Segment Tree.
• Add index of extracted element – count to the answer and insert the index of the currently deleted element into the Segment Tree.
• Repeat the above steps until the string is empty.

Below is the implementation of the above approach:

## C++

 `// C++ Program to implement``// the above approach``#include ``using` `namespace` `std;` `// Function to add index of the deleted character``void` `add_seg(``int` `seg[], ``int` `start, ``int` `end, ``int` `current,``             ``int` `index)``{` `    ``// If index is beyond the range``    ``if` `(index > end or index < start)``        ``return``;` `    ``// Insert the index of the deleted``    ``// character``    ``if` `(start == end) {``        ``seg[current] = 1;``        ``return``;``    ``}``    ``int` `mid = (start + end) / 2;` `    ``// Search over the subtrees to find the``    ``// desired index``    ``add_seg(seg, start, mid, 2 * current + 1, index);``    ``add_seg(seg, mid + 1, end, 2 * current + 2, index);``    ``seg[current]``        ``= seg[2 * current + 1] + seg[2 * current + 2];``}` `// Function to return count of deleted indices``// which are to the left of the current index``int` `deleted(``int` `seg[], ``int` `l, ``int` `r, ``int` `start, ``int` `end,``            ``int` `current)``{``    ``if` `(end < l or start > r)``        ``return` `0;``    ``if` `(start >= l and end <= r)``        ``return` `seg[current];``    ``int` `mid = (start + end) / 2;``    ``return` `deleted(seg, l, r, start, mid, 2 * current + 1)``           ``+ deleted(seg, l, r, mid + 1, end,``                     ``2 * current + 2);``}` `// Function to generate the``// sum of indices``void` `sumOfIndices(string s)``{``    ``int` `N = s.size();``    ``int` `x = ``int``(``ceil``(log2(N)));``    ``int` `seg_size = 2 * (``int``)``pow``(2, x) - 1;``    ``int` `segment[seg_size] = { 0 };` `    ``int` `count = 0;` `    ``// Stores the original index of the``    ``// characters in sorted order of key``    ``map<``int``, queue<``int``> > fre;``    ``for` `(``int` `i = 0; i < N; i++) {``        ``fre[s[i]].push(i);``    ``}` `    ``// Traverse the map``    ``while` `(fre.empty() == ``false``) {` `        ``// Extract smallest index``        ``// of smallest character``        ``auto` `it = fre.begin();` `        ``// Delete the character from the map``        ``// if it has no remaining occurrence``        ``if` `(it->second.empty() == ``true``)``            ``fre.erase(it->first);``        ``else` `{` `            ``// Stores the original index``            ``int` `original_index``                ``= it->second.front();` `            ``// Count of elements removed to``            ``// the left of current character``            ``int` `curr_index``                ``= deleted(segment, 0, original_index - 1,``                          ``0, N - 1, 0);` `            ``// Current index of the current character``            ``int` `new_index``                ``= original_index - curr_index;` `            ``// For 1-based indexing``            ``count += new_index + 1;` `            ``// Insert the deleted index``            ``// in the segment tree``            ``add_seg(segment, 0, N - 1,``                    ``0, original_index);``            ``it->second.pop();``        ``}``    ``}` `    ``// Final answer``    ``cout << count << endl;``}` `// Driver Code``int` `main()``{``    ``string s = ``"geeksforgeeks"``;``    ``sumOfIndices(s);``}`

## Java

 `// Java program to implement``// the above approach``import` `java.io.*;``import` `java.lang.*;``import` `java.util.*;` `class` `GFG{` `// Function to add index of the deleted character``static` `void` `add_seg(``int` `seg[], ``int` `start, ``int` `end,``                    ``int` `current, ``int` `index)``{``    ` `    ``// If index is beyond the range``    ``if` `(index > end || index < start)``        ``return``;` `    ``// Insert the index of the deleted``    ``// characeter``    ``if` `(start == end)``    ``{``        ``seg[current] = ``1``;``        ``return``;``    ``}``    ``int` `mid = (start + end) / ``2``;` `    ``// Search over the subtrees to find the``    ``// desired index``    ``add_seg(seg, start, mid, ``2` `* current + ``1``, index);``    ``add_seg(seg, mid + ``1``, end, ``2` `* current + ``2``, index);``    ``seg[current] = seg[``2` `* current + ``1``] +``                   ``seg[``2` `* current + ``2``];``}` `// Function to return count of deleted indices``// which are to the left of the current index``static` `int` `deleted(``int` `seg[], ``int` `l, ``int` `r, ``int` `start,``                   ``int` `end, ``int` `current)``{``    ``if` `(end < l || start > r)``        ``return` `0``;``    ``if` `(start >= l && end <= r)``        ``return` `seg[current];``        ` `    ``int` `mid = (start + end) / ``2``;``    ` `    ``return` `deleted(seg, l, r, start, mid,``                   ``2` `* current + ``1``) +``           ``deleted(seg, l, r, mid + ``1``, end,``                   ``2` `* current + ``2``);``}` `// Function to generate the``// sum of indices``static` `void` `sumOfIndices(String s)``{``    ``int` `N = s.length();``    ``int` `x = (``int``)(Math.ceil(Math.log(N) / Math.log(``2``)));``    ``int` `seg_size = ``2` `* (``int``)Math.pow(``2``, x) - ``1``;``    ``int` `segment[] = ``new` `int``[seg_size];` `    ``int` `count = ``0``;` `    ``// Stores the original index of the``    ``// characters in sorted order of key``    ``TreeMap> fre = ``new` `TreeMap<>();``    ``for``(``int` `i = ``0``; i < N; i++)``    ``{``        ``int` `key = (``int``)(s.charAt(i));``        ``ArrayDeque que = fre.getOrDefault(``            ``key, ``new` `ArrayDeque<>());``        ``que.addLast(i);``        ``fre.put(key, que);``    ``}` `    ``// Traverse the map``    ``while` `(!fre.isEmpty())``    ``{``        ` `        ``// Extract smallest index``        ``// of smallest character``        ``int` `it = fre.firstKey();` `        ``// Delete the character from the map``        ``// if it has no remaining occurrence``        ``if` `(fre.get(it).size() == ``0``)``            ``fre.remove(it);``        ``else``        ``{``            ``ArrayDeque que = fre.get(it);` `            ``// Stores the original index``            ``int` `original_index = que.getFirst();``            ``// System.out.println(original_index);` `            ``// Count of elements removed to``            ``// the left of current character``            ``int` `curr_index = deleted(segment, ``0``,``                                     ``original_index - ``1``,``                                     ``0``, N - ``1``, ``0``);` `            ``// Current index of the current character``            ``int` `new_index = original_index - curr_index;` `            ``// For 1-based indexing``            ``count += new_index + ``1``;` `            ``// Insert the deleted index``            ``// in the segment tree``            ``add_seg(segment, ``0``, N - ``1``, ``0``,``                    ``original_index);` `            ``que.removeFirst();``            ``fre.put(it, que);``        ``}``    ``}` `    ``// Final answer``    ``System.out.println(count);``}` `// Driver Code``public` `static` `void` `main(String[] args)``{``    ``String s = ``"geeksforgeeks"``;``    ` `    ``sumOfIndices(s);``}``}` `// This code is contributed by Kingash`

## Python3

 `# Python3 program to implement the above approach``import` `math, collections` `# Function to add index of the deleted character``def` `add_seg(seg, start, end, current, index):``    ``# If index is beyond the range``    ``if` `(index > end ``or` `index < start):``        ``return`` ` `    ``# Insert the index of the deleted``    ``# character``    ``if` `(start ``=``=` `end):``        ``seg[current] ``=` `1``        ``return``    ``mid ``=` `int``((start ``+` `end) ``/` `2``)`` ` `    ``# Search over the subtrees to find the``    ``# desired index``    ``add_seg(seg, start, mid, ``2` `*` `current ``+` `1``, index)``    ``add_seg(seg, mid ``+` `1``, end, ``2` `*` `current ``+` `2``, index)``    ``seg[current] ``=` `seg[``2` `*` `current ``+` `1``] ``+` `seg[``2` `*` `current ``+` `2``]`` ` `# Function to return count of deleted indices``# which are to the left of the current index``def` `deleted(seg, l, r, start, end, current):``    ``if` `(end < l ``or` `start > r):``        ``return` `0``    ``if` `(start >``=` `l ``and` `end <``=` `r):``        ``return` `seg[current]``         ` `    ``mid ``=` `int``((start ``+` `end) ``/` `2``)``     ` `    ``return` `deleted(seg, l, r, start, mid, ``2` `*` `current ``+` `1``) ``+` `deleted(seg, l, r, mid ``+` `1``, end, ``2` `*` `current ``+` `2``)`` ` `# Function to generate the``# sum of indices``def` `sumOfIndices(s):``    ``N ``=` `len``(s)``    ``x ``=` `(``int``)(math.ceil(math.log(N) ``/` `math.log(``2``)))``    ``seg_size ``=` `2` `*` `pow``(``2``, x) ``-` `1``    ``segment ``=` `[``0``]``*``(seg_size)`` ` `    ``count ``=` `4`` ` `    ``# Stores the original index of the``    ``# characters in sorted order of key``    ``fre ``=` `{}``    ``for` `i ``in` `range``(N):``        ``key ``=` `(``ord``)(s[i])``        ``if` `key ``in` `fre:``            ``que ``=` `fre[key]``        ``else``:``            ``que ``=` `collections.deque([])``        ``que.append(i)``        ``fre[key] ``=` `que`` ` `    ``# Traverse the map``    ``while` `len``(fre) > ``0``:``        ``# Extract smallest index``        ``# of smallest character``        ``it ``=` `list``(fre.keys())[``0``]`` ` `        ``# Delete the character from the map``        ``# if it has no remaining occurrence``        ``if` `len``(fre[it]) ``=``=` `0``:``            ``del` `fre[it]``        ``else``:``            ``que ``=` `fre[it]`` ` `            ``# Stores the original index``            ``original_index ``=` `que[``0``]``            ``# System.out.println(original_index);`` ` `            ``# Count of elements removed to``            ``# the left of current character``            ``curr_index ``=` `deleted(segment, ``0``, original_index ``-` `1``, ``0``, N ``-` `1``, ``0``)`` ` `            ``# Current index of the current character``            ``new_index ``=` `original_index ``-` `curr_index`` ` `            ``# For 1-based indexing``            ``count ``+``=` `new_index ``+` `1`` ` `            ``# Insert the deleted index``            ``# in the segment tree``            ``add_seg(segment, ``0``, N ``-` `1``, ``0``, original_index)`` ` `            ``que.popleft()``            ``fre[it] ``=` `que`` ` `    ``# Final answer``    ``print``(count)` `s ``=` `"geeksforgeeks"``sumOfIndices(s)` `# This code is contributed by mukesh07.`

## C#

 `// C# program to implement``// the above approach``using` `System;``using` `System.Collections.Generic;``using` `System.Linq;``class` `GFG {``   ` `    ``// Function to add index of the deleted character``    ``static` `void` `add_seg(``int``[] seg, ``int` `start, ``int` `end,``                        ``int` `current, ``int` `index)``    ``{``         ` `        ``// If index is beyond the range``        ``if` `(index > end || index < start)``            ``return``;``     ` `        ``// Insert the index of the deleted``        ``// character``        ``if` `(start == end)``        ``{``            ``seg[current] = 1;``            ``return``;``        ``}``        ``int` `mid = (start + end) / 2;``     ` `        ``// Search over the subtrees to find the``        ``// desired index``        ``add_seg(seg, start, mid, 2 * current + 1, index);``        ``add_seg(seg, mid + 1, end, 2 * current + 2, index);``        ``seg[current] = seg[2 * current + 1] + seg[2 * current + 2];``    ``}``     ` `    ``// Function to return count of deleted indices``    ``// which are to the left of the current index``    ``static` `int` `deleted(``int``[] seg, ``int` `l, ``int` `r, ``int` `start, ``int` `end, ``int` `current)``    ``{``        ``if` `(end < l || start > r)``            ``return` `0;``        ``if` `(start >= l && end <= r)``            ``return` `seg[current];``             ` `        ``int` `mid = (start + end) / 2;``         ` `        ``return` `deleted(seg, l, r, start, mid, 2 * current + 1) +``               ``deleted(seg, l, r, mid + 1, end, 2 * current + 2);``    ``}``     ` `    ``// Function to generate the``    ``// sum of indices``    ``static` `void` `sumOfIndices(``string` `s)``    ``{``        ``int` `N = s.Length;``        ``int` `x = (``int``)(Math.Ceiling(Math.Log(N) / Math.Log(2)));``        ``int` `seg_size = 2 * (``int``)Math.Pow(2, x) - 1;``        ``int``[] segment = ``new` `int``[seg_size];``     ` `        ``int` `count = 4;``     ` `        ``// Stores the original index of the``        ``// characters in sorted order of key``        ``Dictionary<``int``, List<``int``>> fre = ``new` `Dictionary<``int``, List<``int``>>();``        ``for``(``int` `i = 0; i < N; i++)``        ``{``            ``int` `key = (``int``)(s[i]);``            ``List<``int``> que = ``new` `List<``int``>();``            ``if``(fre.ContainsKey(key))``            ``{``                ``que = fre[key];``            ``}``            ``que.Add(i);``            ``fre[key] = que;``        ``}``     ` `        ``// Traverse the map``        ``while` `(fre.Count > 0)``        ``{``             ` `            ``// Extract smallest index``            ``// of smallest character``            ``int` `it = fre.Keys.First();``     ` `            ``// Delete the character from the map``            ``// if it has no remaining occurrence``            ``if` `(fre[it].Count == 0)``                ``fre.Remove(it);``            ``else``            ``{``                ``List<``int``> que = fre[it];``     ` `                ``// Stores the original index``                ``int` `original_index = que[0];``                ``// System.out.println(original_index);``     ` `                ``// Count of elements removed to``                ``// the left of current character``                ``int` `curr_index = deleted(segment, 0, original_index - 1, 0, N - 1, 0);``     ` `                ``// Current index of the current character``                ``int` `new_index = original_index - curr_index;``     ` `                ``// For 1-based indexing``                ``count += new_index + 1;``     ` `                ``// Insert the deleted index``                ``// in the segment tree``                ``add_seg(segment, 0, N - 1, 0, original_index);``     ` `                ``que.RemoveAt(0);``                ``fre[it] = que;``            ``}``        ``}``     ` `        ``// Final answer``        ``Console.Write(count);``    ``}``  ` `  ``static` `void` `Main() {``    ``string` `s = ``"geeksforgeeks"``;``    ``sumOfIndices(s);``  ``}``}` `// This code is contributed by divyeshrabadiya07.`

## Javascript

 ``
Output:
`41`

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

My Personal Notes arrow_drop_up