K'th Non-repeating Character - GeeksforGeeks
Given a string and a number k, find the k'th non-repeating character in the string. Consider a large input string with lacs of characters and a small character set. How to find the character by only doing only one traversal of input string?
Given a string and a number k, find the k'th non-repeating character in the string. Consider a large input string with lacs of characters and a small character set. How to find the character by only doing only one traversal of input string?
Method 3 (O(n) and requires one traversal)
The idea is to use two auxiliary arrays of size 256 (Assuming that characters are stored using 8 bits). The two arrays are:
The idea is to use two auxiliary arrays of size 256 (Assuming that characters are stored using 8 bits). The two arrays are:
count[x] : Stores count of character 'x' in str. If x is not present, then it stores 0. index[x] : Stores indexes of non-repeating characters in str. If a character 'x' is not present or x is repeating, then it stores a value that cannot be a valid index in str[]. For example, length of string.
- Initialize all values in count[] as 0 and all values in index[] as n where n is length of string.
- Traverse the input string str and do following for every character c = str[i].
- Increment count[x].
- If count[x] is 1, then store index of x in index[x], i.e., index[x] = i
- If count[x] is 2, then remove x from index[], i.e., index[x] = n
- Now index[] has indexes of all non-repeating characters. Sort index[] in increasing order so that we get k’th smallest element at index[k]. Note that this step takes O(1) time because there are only 256 elements in index[].
int
kthNonRepeating(string str,
int
k)
{
int
n = str.length();
// count[x] is going to store count of
// character 'x' in str. If x is not present,
// then it is going to store 0.
int
count[MAX_CHAR];
// index[x] is going to store index of character
// 'x' in str. If x is not present or x is
// repeating, then it is going to store a value
// (for example, length of string) that cannot be
// a valid index in str[]
int
index[MAX_CHAR];
// Initialize counts of all characters and indexes
// of non-repeating characters.
for
(
int
i = 0; i < MAX_CHAR; i++)
{
count[i] = 0;
index[i] = n;
// A value more than any index
// in str[]
}
// Traverse the input string
for
(
int
i = 0; i < n; i++)
{
// Find current character and increment its
// count
char
x = str[i];
++count[x];
// If this is first occurrence, then set value
// in index as index of it.
if
(count[x] == 1)
index[x] = i;
// If character repeats, then remove it from
// index[]
if
(count[x] == 2)
index[x] = n;
}
// Sort index[] in increasing order. This step
// takes O(1) time as size of index is 256 only
sort(index, index+MAX_CHAR);
// After sorting, if index[k-1] is value, then
// return it, else return -1.
return
(index[k-1] != n)? index[k-1] : -1;
}
Method 1 (Simple : O(n2)
A Simple Solution is to run two loops. Start traversing from left side. For every character, check if it repeats or not. If the character doesn’t repeat, increment count of non-repeating characters. When the count becomes k, return the character.
A Simple Solution is to run two loops. Start traversing from left side. For every character, check if it repeats or not. If the character doesn’t repeat, increment count of non-repeating characters. When the count becomes k, return the character.
Method 2 (O(n) but requires two traversals)
- Create an empty hash.
- Scan input string from left to right and insert values and their counts in the hash.
- Scan input string from left to right and keep count of characters with counts more than 1. When count becomes k, return the character.