Partiton the string in two parts such that both parts have at least k different characters

Given a string of lowercase English alphabets and an integer 0 < K <= 26. The task is to divide the string into two parts (also print them) such that both parts have at least k different characters. If there are more than one answers possible, print one having the smallest left part. If there is no such answers, print “Not Possible”.

Examples:

Input : str = “geeksforgeeks”, k = 4
Output : geeks , forgeeks
The string can be divided into two parts as “geeks” and “forgeeks”. Since “geeks” has four different characters ‘g’, ‘e’, ‘k’ and ‘s’ and this is the smallest left part, “forgeeks” has also at least four different characters.



Input : str = “aaaabbbb”, k = 2
Output :Not Possible

Approach :

  • Idea is to count the number of distinct characters using a Hashmap.
  • If the count of the distinct variable becomes equal to k, then the left part of the string is found so store this index, break the loop and unmark all the characters.
  • Now run a loop from where the left string ends to end of the given string and repeat the same process as it was done to find the left string.
  • If count is greater than or equal to k, then right string could be found otherwise print “Not Possible”.
  • If it is possible , then print the left string and right string.

Below is the implementation of the above approach

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implemenattion of the above approach
#include <iostream>
#include <map>
using namespace std;
  
// Function to find the partition of the
// string such that both parts have at
// least k different characters
void division_of_string(string str, int k)
{
    // Length of the string
    int n = str.size();
  
    // To check if the current 
    // character is already found
    map<char, bool> has;
  
    int ans, cnt = 0, i = 0;
  
    // Count number of different
    // characters in the left part
    while (i < n) {
  
        // If current character is not 
        // already found, increase cnt by 1
        if (!has[str[i]]) {
            cnt++;
            has[str[i]] = true;
        }
  
        // If count becomes equal to k, we've 
        // got the first part, therefore,
        // store current index and break the loop
        if (cnt == k) {
            ans = i;
            break;
        }
  
        i++;
    }
  
    // Clear the map
    has.clear();
  
    // Assign cnt as 0
    cnt = 0;
  
    while (i < n) {
  
        // If the current character is not 
        // already found, increase cnt by 1
        if (!has[str[i]]) {
            cnt++;
            has[str[i]] = true;
        }
  
        // If cnt becomes equal to k, the
        // second part also have k different
        // characters so break it
        if (cnt == k) {
            break;
        }
  
        i++;
    }
  
    // If the second part has less than
    // k different characters, then 
    // print "Not Possible"
    if (cnt < k) {
        cout << "Not possible" << endl;
    }
  
    // Otherwise print both parts
    else {
        i = 0;
        while (i <= ans) {
            cout << str[i];
            i++;
        }
        cout << endl;
  
        while (i < n) {
            cout << str[i];
            i++;
        }
        cout << endl;
    }
  
    cout << endl;
}
  
// Driver code
int main()
{
    string str = "geeksforgeeks";
    int k = 4;
  
    // Function call
    division_of_string(str, k);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.*;
  
class GFG 
{
  
// Function to find the partition of the
// string such that both parts have at
// least k different characters
static void division_of_string(char[] str, int k)
{
    // Length of the string
    int n = str.length;
  
    // To check if the current 
    // character is already found
    Map<Character, Boolean> has = new HashMap<>();
  
    int ans = 0, cnt = 0, i = 0;
  
    // Count number of different
    // characters in the left part
    while (i < n)
    {
  
        // If current character is not 
        // already found, increase cnt by 1
        if (!has.containsKey(str[i])) 
        {
            cnt++;
            has.put(str[i], true);
        }
  
        // If count becomes equal to k, we've 
        // got the first part, therefore,
        // store current index and break the loop
        if (cnt == k) 
        {
            ans = i;
            break;
        }
  
        i++;
    }
  
    // Clear the map
    has.clear();
  
    // Assign cnt as 0
    cnt = 0;
  
    while (i < n) 
    {
  
        // If the current character is not 
        // already found, increase cnt by 1
        if (!has.containsKey(str[i]))
        {
            cnt++;
            has.put(str[i], true);
        }
  
        // If cnt becomes equal to k, the
        // second part also have k different
        // characters so break it
        if (cnt == k)
        {
            break;
        }
  
        i++;
    }
  
    // If the second part has less than
    // k different characters, then 
    // print "Not Possible"
    if (cnt < k)
    {
        System.out.println("Not possible");
    }
  
    // Otherwise print both parts
    else 
    {
        i = 0;
        while (i <= ans)
        {
            System.out.print(str[i]);
            i++;
        }
        System.out.println("");
  
        while (i < n) 
        {
            System.out.print(str[i]);
            i++;
        }
        System.out.println("");
    }
  
    System.out.println("");
}
  
// Driver code
public static void main(String[] args) 
{
    String str = "geeksforgeeks";
    int k = 4;
  
    // Function call
    division_of_string(str.toCharArray(), k);
}
}
  
// This code is contributed by 29AjayKumar

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implemenattion of the above approach
  
# Function to find the partition of the
# string such that both parts have at
# least k different characters
def division_of_string(string, k) :
      
    # Length of the string
    n = len(string);
  
    # To check if the current 
    # character is already found
    has = {};
  
    cnt = 0; i = 0;
  
    # Count number of different
    # characters in the left part
    while (i < n) :
  
        # If current character is not 
        # already found, increase cnt by 1
        if string[i] not in has :
            cnt += 1;
            has[string[i]] = True;
  
        # If count becomes equal to k, we've 
        # got the first part, therefore,
        # store current index and break the loop
        if (cnt == k) :
            ans = i;
            break;
  
        i += 1;
  
    # Clear the map
    has.clear();
  
    # Assign cnt as 0
    cnt = 0;
  
    while (i < n) :
  
        # If the current character is not 
        # already found, increase cnt by 1
        if (string[i] not in has) :
            cnt += 1;
            has[string[i]] = True;
  
        # If cnt becomes equal to k, the
        # second part also have k different
        # characters so break it
        if (cnt == k) :
            break;
  
        i += 1;
  
    # If the second part has less than
    # k different characters, then 
    # print "Not Possible"
    if (cnt < k) :
        print("Not possible",end = "");
  
    # Otherwise print both parts
    else :
        i = 0;
        while (i <= ans) :
            print(string[i],end= "");
            i += 1;
      
        print();
  
        while (i < n) :
            print(string[i],end="");
            i += 1;
              
        print()
  
# Driver code
if __name__ == "__main__":
  
    string = "geeksforgeeks";
    k = 4;
  
    # Function call
    division_of_string(string, k);
  
# This code is contributed by AnkitRai01

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
using System.Collections.Generic;
  
class GFG 
{
  
// Function to find the partition of the
// string such that both parts have at
// least k different characters
static void division_of_string(char[] str, int k)
{
    // Length of the string
    int n = str.Length;
  
    // To check if the current 
    // character is already found
    Dictionary<char,bool> has = new Dictionary<char,bool> ();
  
    int ans = 0, cnt = 0, i = 0;
  
    // Count number of different
    // characters in the left part
    while (i < n)
    {
  
        // If current character is not 
        // already found, increase cnt by 1
        if (!has.ContainsKey(str[i])) 
        {
            cnt++;
            has.Add(str[i], true);
        }
  
        // If count becomes equal to k, we've 
        // got the first part, therefore,
        // store current index and break the loop
        if (cnt == k) 
        {
            ans = i;
            break;
        }
  
        i++;
    }
  
    // Clear the map
    has.Clear();
  
    // Assign cnt as 0
    cnt = 0;
  
    while (i < n) 
    {
  
        // If the current character is not 
        // already found, increase cnt by 1
        if (!has.ContainsKey(str[i]))
        {
            cnt++;
            has.Add(str[i], true);
        }
  
        // If cnt becomes equal to k, the
        // second part also have k different
        // characters so break it
        if (cnt == k)
        {
            break;
        }
  
        i++;
    }
  
    // If the second part has less than
    // k different characters, then 
    // print "Not Possible"
    if (cnt < k)
    {
        Console.WriteLine("Not possible");
    }
  
    // Otherwise print both parts
    else
    {
        i = 0;
        while (i <= ans)
        {
            Console.Write(str[i]);
            i++;
        }
        Console.WriteLine("");
  
        while (i < n) 
        {
            Console.Write(str[i]);
            i++;
        }
        Console.WriteLine("");
    }
  
    Console.WriteLine("");
}
  
// Driver code
public static void Main(String[] args) 
{
    String str = "geeksforgeeks";
    int k = 4;
  
    // Function call
    division_of_string(str.ToCharArray(), k);
}
}
  
// This code is contributed by Rajput-Ji

chevron_right


Output:

geeks
forgeeks

Time Complexity: O(N) where N is the length of given string.



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.