Skip to content
Related Articles

Related Articles

Improve Article

Maximum non-repeating characters after removing K characters

  • Difficulty Level : Hard
  • Last Updated : 31 May, 2021

Given a string S containing lowercase English alphabets of length N and an integer K such that K ≤ N. The task is to find the maximum number of non-repeating characters after removing K characters from the string.

Examples:

Input: S = “geeksforgeeks”, K = 3
Output: 6
Explanation:
Remove 1 occurrences of each g, k and s so the final string is “geeksforee” and the 6 distinct elements are g, k, s, f, o and r

Input: S = “aabbccddeeffgghh”, k = 1
Output: 1
Explanation:
Remove 1 occurrences of any character we will have only one character which will non repeating.

Naive Approach: The naive idea is to delete all possible K characters among the given string and then find the non-repeating characters in all the formed string. Print the maximum among all the count of non-repeating characters.
Time Complexity: O(N!), where N is the length of the given string.
Auxiliary Space: O(N-K)

Efficient Approach: To optimize the above approach,  



The idea is to delete K characters in increasing order of frequency whose frequency is at least 2 to get the count of maximum non-repeating characters. 
 

Below are the steps: 

  1. Create a hash table to store the frequency of each element.
  2. Insert the frequency of each element in a vector V and sort the vector V in increasing order.
  3. For each element(say currentElement) of vector V find the minimum among K and currentElement – 1 and decrease both K and V[i] by the minimum of the two.
  4. Repeat the above step until K is non-zero.
  5. The count of 1s in vector V gives the maximum number of non-repeating characters after deleting K characters.

 Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find maximum distinct
// character after removing K character
int maxDistinctChar(string s, int n, int k)
{
    // Freq implemented as hash table to
    // store frequency of each character
    unordered_map<int, int> freq;
 
    // Store frequency of each character
    for (int i = 0; i < n; i++)
        freq[s[i]]++;
 
    vector<int> v;
 
    // Insert each frequency in v
    for (auto it = freq.begin();
         it != freq.end(); it++) {
        v.push_back(it->second);
    }
 
    // Sort the freq of character in
    // non-decresing order
    sort(v.begin(), v.end());
 
    // Traverse the vector
    for (int i = 0; i < v.size(); i++) {
        int mn = min(v[i] - 1, k);
 
        // Update v[i] and k
        v[i] -= mn;
        k -= mn;
    }
 
    // If K is still not 0
    if (k > 0) {
 
        for (int i = 0; i < v.size(); i++) {
            int mn = min(v[i], k);
            v[i] -= mn;
            k -= mn;
        }
    }
 
    // Store the final answer
    int res = 0;
    for (int i = 0; i < v.size(); i++)
 
        // Count this character if freq 1
        if (v[i] == 1)
            res++;
 
    // Return count of distinct characters
    return res;
}
 
// Driver Code
int main()
{
    // Given string
    string S = "geeksforgeeks";
 
    int N = S.size();
 
    // Given k
    int K = 1;
 
    // Function Call
    cout << maxDistinctChar(S, N, K);
 
    return 0;
}

Java




// Java program for the above approach
import java.util.*;
class GFG{
 
// Function to find maximum distinct
// character after removing K character
static int maxDistinctChar(char []s, int n, int k)
{
    // Freq implemented as hash table to
    // store frequency of each character
    HashMap<Integer,
            Integer> freq  = new HashMap<Integer,
                                         Integer>();
 
    // Store frequency of each character
    for (int i = 0; i < n; i++)
    {
        if(freq.containsKey((int)s[i]))
        {
            freq.put((int)s[i],
                     freq.get((int)s[i]) + 1);
        }
        else
        {
            freq.put((int)s[i], 1);
        }
    }
 
    Vector<Integer> v = new Vector<Integer>();
 
    // Insert each frequency in v
    for (Map.Entry<Integer, Integer> it : freq.entrySet())
    {
        v.add(it.getValue());
    }
 
    // Sort the freq of character in
    // non-decresing order
    Collections.sort(v);
 
    // Traverse the vector
    for (int i = 0; i < v.size(); i++)
    {
        int mn = Math.min(v.get(i) - 1, k);
 
        // Update v[i] and k
        v.set(i, v.get(i) - mn);
        k -= mn;
    }
 
    // If K is still not 0
    if (k > 0)
    {
        for (int i = 0; i < v.size(); i++)
        {
            int mn = Math.min(v.get(i), k);
            v.set(i, v.get(i) - mn);
            k -= mn;
        }
    }
 
    // Store the final answer
    int res = 0;
    for (int i = 0; i < v.size(); i++)
 
        // Count this character if freq 1
        if (v.get(i) == 1)
            res++;
 
    // Return count of distinct characters
    return res;
}
 
// Driver Code
public static void main(String[] args)
{
    // Given String
    String S = "geeksforgeeks";
 
    int N = S.length();
 
    // Given k
    int K = 1;
 
    // Function Call
    System.out.print(maxDistinctChar(S.toCharArray(),
                                     N, K));
}
}
 
// This code is contributed by shikhasingrajput

Python3




# Python3 program for the above approach
from collections import defaultdict
 
# Function to find maximum distinct
# character after removing K character
def maxDistinctChar(s, n, k):
 
    # Freq implemented as hash table to
    # store frequency of each character
    freq = defaultdict (int)
 
    # Store frequency of each character
    for i in range (n):
        freq[s[i]] += 1
 
    v = []
 
    # Insert each frequency in v
    for it in freq.values():
        v.append(it)
 
    # Sort the freq of character in
    # non-decresing order
    v.sort()
 
    # Traverse the vector
    for i in range (len(v)):
        mn = min(v[i] - 1, k)
 
        # Update v[i] and k
        v[i] -= mn
        k -= mn
 
    # If K is still not 0
    if (k > 0):
        for i in range (len(v)):
            mn = min(v[i], k);
            v[i] -= mn
            k -= mn
 
    # Store the final answer
    res = 0
    for i in range (len(v)):
 
        # Count this character if freq 1
        if (v[i] == 1):
            res += 1
 
    # Return count of distinct characters
    return res
 
# Driver Code
if __name__ == "__main__":
   
    # Given string
    S = "geeksforgeeks"
 
    N = len(S)
 
    # Given k
    K = 1
 
    # Function Call
    print(maxDistinctChar(S, N, K))
 
# This code is contributed by Chitranayal

C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
// Function to find maximum distinct
// character after removing K character
static int maxDistinctChar(char []s, int n, int k)
{
     
    // Freq implemented as hash table to
    // store frequency of each character
    Dictionary<int,
               int> freq = new Dictionary<int,
                                          int>();
 
    // Store frequency of each character
    for(int i = 0; i < n; i++)
    {
        if(freq.ContainsKey((int)s[i]))
        {
            freq[(int)s[i]] = freq[(int)s[i]] + 1;
        }
        else
        {
            freq.Add((int)s[i], 1);
        }
    }
 
    List<int> v = new List<int>();
 
    // Insert each frequency in v
    foreach(KeyValuePair<int, int> it in freq)
    {
        v.Add(it.Value);
    }
 
    // Sort the freq of character in
    // non-decresing order
    v.Sort();
 
    // Traverse the vector
    for(int i = 0; i < v.Count; i++)
    {
        int mn = Math.Min(v[i] - 1, k);
 
        // Update v[i] and k
        v[i] = v[i] - mn;
        k -= mn;
    }
 
    // If K is still not 0
    if (k > 0)
    {
        for(int i = 0; i < v.Count; i++)
        {
            int mn = Math.Min(v[i], k);
            v[i] = v[i] - mn;
            k -= mn;
        }
    }
 
    // Store the readonly answer
    int res = 0;
    for(int i = 0; i < v.Count; i++)
 
        // Count this character if freq 1
        if (v[i] == 1)
            res++;
 
    // Return count of distinct characters
    return res;
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Given String
    String S = "geeksforgeeks";
 
    int N = S.Length;
 
    // Given k
    int K = 1;
 
    // Function call
    Console.Write(maxDistinctChar(S.ToCharArray(),
                                  N, K));
}
}
 
// This code is contributed by Amit Katiyar

Javascript




<script>
 
// JavaScript program for the above approach
 
// Function to find maximum distinct
// character after removing K character
function maxDistinctChar(s, n, k)
{
    // Freq implemented as hash table to
    // store frequency of each character
    var freq = new Map();
 
    // Store frequency of each character
    for (var i = 0; i < n; i++)
    {
        if(freq.has(s[i]))
            freq.set(s[i], freq.get(s[i])+1)
        else   
            freq.set(s[i], 1)
    }
 
    var v = [];
 
    // Insert each frequency in v
    freq.forEach((value,key) => {
        
        v.push(value);
    });
 
    // Sort the freq of character in
    // non-decresing order
    v.sort()
 
    // Traverse the vector
    for (var i = 0; i < v.length; i++) {
        var mn = Math.min(v[i] - 1, k);
 
        // Update v[i] and k
        v[i] -= mn;
        k -= mn;
    }
 
    // If K is still not 0
    if (k > 0) {
 
        for (var i = 0; i < v.length; i++) {
            var mn = Math.min(v[i], k);
            v[i] -= mn;
            k -= mn;
        }
    }
 
    // Store the final answer
    var res = 0;
    for (var i = 0; i < v.length; i++)
 
        // Count this character if freq 1
        if (v[i] == 1)
            res++;
 
    // Return count of distinct characters
    return res;
}
 
// Driver Code
 
// Given string
var S = "geeksforgeeks";
var N = S.length;
 
// Given k
var K = 1;
 
// Function Call
document.write( maxDistinctChar(S, N, K));
 
</script>
Output: 
4

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

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 :