Open In App

Find Kth distinct character from start of given String

Last Updated : 25 Aug, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given a string str of size N containing all possible characters including integers. Print Kth distinct character from the starting of the given string. If K is more than number of distinct characters, print -1.

Note: The uppercase and lowercase letters are considered different.

Examples:

Input: str = “prophet1999”, K = 4
Output: h
Explanation: First distinct character is ‘p’.
Second distinct character is ‘r’.
Third distinct character is ‘o’.
Fourth distinct character is ‘h’.
‘p’ is not the 4th character because it is already present before this point and not distinct.

Input: str = “GeeksForGeeks”, K = 2
Output: e
Explanation: First distinct character is ‘G’.
Second distinct character is ‘e’.

 

Naive Approach: A simple solution is to use two nested loops where outer loop picks characters from left to right, and inner loop checks if the picked character is present somewhere else and makes it null character ‘\0’. If i-th element is not ‘\0’, then increment distinct elements count. If distinct element count becomes K, return current element.

 Below is the implementation of the above approach.

C++14




// C++ program to implement above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to print the Kth distinct character
int printKDistinct(string& str, int& K)
{
    int distinct = 0, i, j, N = str.length();
 
    if (K <= 0)
        return -1;
 
    for (i = 0; i < N; i++) {
        for (j = i + 1; j < N; j++) {
            if (str[i] == str[j])
                str[j] = '\0';
        }
        if (str[i] != '\0')
            distinct++;
        if (distinct == K)
            return str[i];
    }
    return -1;
}
 
// Driver code
int main()
{
    string str = "GeeksForGeeks";
    int K = 2;
    int ans = printKDistinct(str, K);
    if (ans == -1)
        cout << -1;
    else
        cout << (char)ans;
    return 0;
}


Java




// Java code to implement the approach
import java.io.*;
import java.util.*;
 
class GFG {
    // Function to print the Kth distinct character
    static int printKDistinct(char[] str, int K)
    {
        int distinct = 0, i, j, N = str.length;
 
        if (K <= 0)
            return -1;
 
        for (i = 0; i < N; i++) {
            for (j = i + 1; j < N; j++) {
                if (str[i] == str[j])
                    str[j] = '\0';
            }
            if (str[i] != '\0')
                distinct++;
            if (distinct == K)
                return str[i];
        }
        return -1;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        String str = "GeeksForGeeks";
        int K = 2;
        int ans = printKDistinct(str.toCharArray(), K);
        if (ans == -1)
            System.out.println(-1);
        else
            System.out.println((char)ans);
    }
}
// This code is contributed by Karandeep1234


Python3




# Python program to implement above approach
 
# Function to print the Kth distinct character
def printKDistinct(Str, K):
    distinct,N = 0 ,len(Str)
 
    if (K <= 0):
        return -1
 
    for i in range(N):
        for j in range(i + 1,N):
            if (Str[i] == Str[j]):
                Str.replace(Str[j],'\0')
        if (Str[i] != '\0'):
            distinct += 1
        if (distinct == K):
            return Str[i]
    return -1
 
# Driver code
Str = "GeeksForGeeks"
K = 2
ans = printKDistinct(Str, K)
if (ans == -1):
    print(-1)
else:
    print(ans)
     
# This code is contributed by shinjanpatra


C#




// C# code to implement the approach
using System;
 
public class GFG
{
   
  // Function to print the Kth distinct character
  static int printKDistinct(char[] str, int K)
  {
    int distinct = 0, i, j, N = str.Length;
 
    if (K <= 0)
      return -1;
 
    for (i = 0; i < N; i++) {
      for (j = i + 1; j < N; j++) {
        if (str[i] == str[j])
          str[j] = '\0';
      }
      if (str[i] != '\0')
        distinct++;
      if (distinct == K)
        return str[i];
    }
    return -1;
  }
 
  // Driver code
  public static void Main(String[] args)
  {
    String str = "GeeksForGeeks";
    int K = 2;
    int ans = printKDistinct(str.ToCharArray(), K);
    if (ans == -1)
      Console.WriteLine(-1);
    else
      Console.WriteLine((char)ans);
  }
}
 
// This code is contributed by shikhasingrajput


Javascript




<script>
// Javascript program to implement above approach
 
// Function to print the Kth distinct character
function printKDistinct(str, K) {
    let distinct = 0, i, j, N = str.length;
 
    if (K <= 0)
        return -1;
 
    for (i = 0; i < N; i++) {
        for (j = i + 1; j < N; j++) {
            if (str[i] == str[j])
                str[j] = '\0';
        }
        if (str[i] != '\0')
            distinct++;
        if (distinct == K)
            return str[i];
    }
    return -1;
}
 
// Driver code
let str = "GeeksForGeeks";
let K = 2;
let ans = printKDistinct(str, K);
if (ans == -1)
    document.write(-1);
else
    document.write(ans);
     
    // This code is contributed by saurabh_jaiswal.
</script>


Output

e

Time Complexity: O(N * N), since there are two nested loops inside each other in the worst case if the first loop run for all N elements, then for each element the inner loop also runs N*N times.
Auxiliary Space: O(1), since there is no extra array is used so constant space is used

 

Using Sets: An Efficient approach is to use Sets to store characters by traversing the given string and check its size at each iteration. If its size becomes equal to K then return the current character. Otherwise, K is greater than the number of distinct characters present in the string so return -1.

 

Below is the implementation of the above approach.

 

C++14




// C++ program to implement the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to print the Kth distinct character
int printKDistinct(string& str, int& K)
{
    set<int> unique;
    int N = str.length();
 
    for (int i = 0; i < N; i++) {
        unique.insert(str[i]);
        if (unique.size() == K)
            return str[i];
    }
    return -1;
}
 
// Driver code
int main()
{
    string str = "GeeksForGeeks";
    int K = 2;
    int ans = printKDistinct(str, K);
    if (ans == -1)
        cout << -1;
    else
        cout << (char)ans;
    return 0;
}


Java




// Java code to implement the approach
import java.io.*;
import java.util.*;
 
class GFG
{
  // Function to print the Kth distinct character
  static int printKDistinct(String str, int K)
  {
    HashSet<Character> unique = new HashSet<>();
    int N = str.length();
 
    for (int i = 0; i < N; i++) {
      unique.add(str.charAt(i));
      if (unique.size() == K)
        return str.charAt(i);
    }
    return -1;
  }
 
  // Driver code
  public static void main(String[] args)
  {
    String str = "GeeksForGeeks";
    int K = 2;
    int ans = printKDistinct(str, K);
    if (ans == -1)
      System.out.println(-1);
    else
      System.out.println((char)ans);
  }
}
 
// This code is contributed by Karandeep1234


Python3




# Python 3 program to implement the approach
 
# Function to print the Kth distinct character
def printKDistinct(st,  K):
 
    unique = set()
    N = len(st)
 
    for i in range(N):
        unique.add(st[i])
        if (len(unique) == K):
            return st[i]
 
    return -1
 
# Driver code
if __name__ == "__main__":
 
    st = "GeeksForGeeks"
    K = 2
    ans = printKDistinct(st, K)
    if (ans == -1):
        print(-1)
    else:
        print(ans)
 
        # This code is contributed by ukasp.


C#




// C# code to implement the approach
 
using System;
using System.Collections.Generic;
 
public class GFG
{
  // Function to print the Kth distinct character
  static int printKDistinct(String str, int K)
  {
    HashSet<char> unique = new HashSet<char>();
    int N = str.Length;
 
    for (int i = 0; i < N; i++) {
      unique.Add(str[i]);
      if (unique.Count == K)
        return str[i];
    }
    return -1;
  }
 
  // Driver code
  public static void Main(String[] args)
  {
    String str = "GeeksForGeeks";
    int K = 2;
    int ans = printKDistinct(str, K);
    if (ans == -1)
      Console.WriteLine(-1);
    else
      Console.WriteLine((char)ans);
  }
}
 
// This code is contributed by shikhasingrajput


Javascript




<script>
        // JavaScript code for the above approach
 
        // Function to print the Kth distinct character
        function printKDistinct(str, K) {
            let unique = new Set();
            let N = str.length;
 
            for (let i = 0; i < N; i++) {
                unique.add(str[i]);
                if (unique.size == K)
                    return str[i];
            }
            return -1;
        }
 
        // Driver code
        let str = "GeeksForGeeks";
        let K = 2;
        let ans = printKDistinct(str, K);
        if (ans == -1)
            document.write(-1);
        else
            document.write(ans);
 
       // This code is contributed by Potta Lokesh
    </script>


Output

e

Time Complexity: O(N * logN) since there is one loop and each insert operation takes log N time, overall complexity turns out to be NlogN

For Python : Time complexity is 0(n) since there is one loop and each insert operation takes 0(1) time unless size is not so large so overall complexity turns out to be 0(n).

Auxiliary Space: O(N) since there is a set used and in worst case all elements will be inserted into the set thus auxiliary space turns out to be O(N)

 

Using Hash-Map: Another efficient solution is to use Hashing. Follow the steps mentioned below:

 

  • Create an empty hash table.
  • Traverse input string from left to right and check whether current character is present in the map or not.
  • If it is not present in the map, increment distinct.
  • If distinct becomes K, return current character.
  • If K is greater than the number of distinct characters present in the string then return -1.

 

Below is the implementation of the above approach.

 

C++14




// C++ program to implement the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to print the Kth distinct character
int printKDistinct(string& str, int& K)
{
    int distinct = 0, N = str.length();
    unordered_map<char, bool> freq;
 
    for (int i = 0; i < N; i++) {
        if (!freq[str[i]])
            distinct++;
        freq[str[i]] = 1;
        if (distinct == K)
            return str[i];
    }
    return -1;
}
 
// Driver code
int main()
{
    string str = "GeeksForGeeks";
    int K = 2;
    int ans = printKDistinct(str, K);
    if (ans == -1)
        cout << -1;
    else
        cout << (char)ans;
    return 0;
}


Java




/*package whatever //do not write package name here */
import java.util.*;
 
class GFG
{
   
  // Function to print the Kth distinct character
  static int printKDistinct(String str, int K)
  {
    int distinct = 0;
    int N = str.length();
    Map<Character,Boolean> freq = new HashMap<>();
 
    for (int i = 0; i < N; i++) {
      if (!freq.containsKey(str.charAt(i)))
        distinct++;
      freq.put(str.charAt(i),true);
      if (distinct == K)
        return str.charAt(i);
    }
    return -1;
  }
 
  public static void main (String[] args) {
    String str = "GeeksForGeeks";
    int K = 2;
    int ans = printKDistinct(str, K);
    if (ans == -1)
      System.out.println(-1);
    else
      System.out.println((char)ans);
  }
}
 
// This code is contributed by aadityaburujwale


Python3




# Python program to implement the approach
 
# Function to print the Kth distinct character
def printKDistinct(Str, K):
    distinct,N = 0,len(Str)
    freq = dict()
 
    for i in range(N):
        if (Str[i] not in freq):
            distinct += 1
            freq[Str[i]] = 1
        if (distinct == K):
            return Str[i]
    return -1
 
# Driver code
Str = "GeeksForGeeks"
K = 2
ans = printKDistinct(Str, K)
if (ans == -1):
    print(-1)
else:
    print(ans)
 
# This code is contributed by shinjanpatra


C#




// Include namespace system
using System;
using System.Collections.Generic;
using System.Collections;
 
public class GFG
{
   
  // Function to print the Kth distinct character
  public static int printKDistinct(String str, int K)
  {
    var distinct = 0;
    var N = str.Length;
    var freq = new Dictionary<char, bool>();
    for (int i = 0; i < N; i++)
    {
      if (!freq.ContainsKey(str[i]))
      {
        distinct++;
      }
      freq[str[i]] = true;
      if (distinct == K)
      {
        return str[i];
      }
    }
    return -1;
  }
  public static void Main(String[] args)
  {
    var str = "GeeksForGeeks";
    var K = 2;
    var ans = GFG.printKDistinct(str, K);
    if (ans == -1)
    {
      Console.WriteLine(-1);
    }
    else
    {
      Console.WriteLine((char)ans);
    }
  }
}
 
// This code is contributed by aadityaburujwale


Javascript




<script>
    // JavaScript program to implement the approach
 
    // Function to print the Kth distinct character
    const printKDistinct = (str, K) => {
        let distinct = 0, N = str.length;
        let freq = {};
 
        for (let i = 0; i < N; i++) {
            if (!freq[str[i]])
                distinct++;
            freq[str[i]] = 1;
            if (distinct == K)
                return str[i];
        }
        return -1;
    }
 
    // Driver code
 
    let str = "GeeksForGeeks";
    let K = 2;
    let ans = printKDistinct(str, K);
    if (ans == -1)
        document.write(-1);
    else
        document.write(ans);
 
// This code is contributed by rakeshsahni
 
</script>


 
 

Output

e

 

Time Complexity: O(N), only one traversal of the array is required to carry out all the operations
Auxiliary Space: O(N), since there is an unordered map used and in the worst case all elements will be inserted into the set thus auxiliary space turns out to be O(N)

 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads