First non-repeating character of given string
Given a string s of lowercase English letters, the task is to find the first non-repeating character. If there is no such character, return '$'.
Examples:
Input: s = "geeksforgeeks"
Output: 'f'
Explanation: 'f' is the first character in the string which does not repeat.Input: s = "racecar"
Output: 'e'
Explanation: 'e' is the only character in the string which does not repeat.Input: "aabbccc"
Output: '$'
Explanation: All the characters in the given string are repeating.
Table of Content
[Naive Approach] Using Nested Loop – O(n^2) Time and O(1) Space
The idea is to use two nested loops, the outer loop for picking an element and the inner loop for finding another occurrence of the picked character in the string. As soon as we find a character which has only one occurrence in the input string, return it. If all characters have multiple occurrences, return '$'.
#include <bits/stdc++.h>
using namespace std;
char nonRep(string &s) {
int n = s.length();
for (int i = 0; i < n; ++i) {
bool found = false;
for (int j = 0; j < n; ++j) {
if (i != j && s[i] == s[j]) {
found = true;
break;
}
}
if (!found)
return s[i];
}
return '$';
}
int main() {
string s = "racecar";
cout << nonRep(s);
return 0;
}
public class GFG {
public static char nonRep(String s) {
int n = s.length();
for (int i = 0; i < n; ++i) {
boolean found = false;
for (int j = 0; j < n; ++j) {
if (i != j && s.charAt(i) == s.charAt(j)) {
found = true;
break;
}
}
if (!found)
return s.charAt(i);
}
return '$';
}
public static void main(String[] args) {
String s = "racecar";
System.out.println(nonRep(s));
}
}
def nonRep(s):
n = len(s)
for i in range(n):
found = False
for j in range(n):
if i != j and s[i] == s[j]:
found = True
break
if not found:
return s[i]
return '$'
s = "racecar"
print(nonRep(s))
using System;
class GFG {
public static char nonRep(string s) {
int n = s.Length;
for (int i = 0; i < n; ++i) {
bool found = false;
for (int j = 0; j < n; ++j) {
if (i != j && s[i] == s[j]) {
found = true;
break;
}
}
if (!found)
return s[i];
}
return '$';
}
static void Main(string[] args) {
string s = "racecar";
Console.WriteLine(nonRep(s));
}
}
function nonRep(s) {
let n = s.length;
for (let i = 0; i < n; ++i) {
let found = false;
for (let j = 0; j < n; ++j) {
if (i !== j && s[i] === s[j]) {
found = true;
break;
}
}
if (!found) return s[i];
}
return '$';
}
let s = "racecar";
console.log(nonRep(s));
Output
e
[Efficient Approach 1] Using Frequency Array (Two Traversal) – O(2*n) Time and O(MAX_CHAR ) Space
The efficient approach is to either use an array of size MAX_CHAR to store the frequencies of each character. Traverse the input string twice:
- First traversal is to count the frequency of each character.
- Second traversal to find the first character in string with a frequency of one.
#include <bits/stdc++.h>
using namespace std;
const int MAX_CHAR = 26;
char nonRep(const string &s) {
vector<int> freq(MAX_CHAR, 0);
for (char c : s) {
freq[c - 'a']++;
}
// Find the first character with frequency 1
for (char c : s) {
if (freq[c - 'a'] == 1) {
return c;
}
}
return '$';
}
int main() {
string s = "geeksforgeeks";
cout << nonRep(s) << endl;
return 0;
}
import java.util.*;
public class GFG {
private static final int MAX_CHAR = 26;
public static char nonRep(String s) {
int[] freq = new int[MAX_CHAR];
for (char c : s.toCharArray()) {
freq[c - 'a']++;
}
// Find the first character with frequency 1
for (char c : s.toCharArray()) {
if (freq[c - 'a'] == 1) {
return c;
}
}
return '$';
}
public static void main(String[] args) {
String s = "geeksforgeeks";
System.out.println(nonRep(s));
}
}
MAX_CHAR = 26
def nonRep(s):
freq = [0] * MAX_CHAR
for c in s:
freq[ord(c) - ord('a')] += 1
# Find the first character with frequency 1
for c in s:
if freq[ord(c) - ord('a')] == 1:
return c
return '$'
s = "geeksforgeeks"
print(nonRep(s))
using System;
class GFG {
const int MAX_CHAR = 26;
static char nonRep(string s) {
int[] freq = new int[MAX_CHAR];
foreach (char c in s) {
freq[c - 'a']++;
}
// Find the first character with frequency 1
foreach (char c in s) {
if (freq[c - 'a'] == 1) {
return c;
}
}
return '$';
}
static void Main() {
string s = "geeksforgeeks";
Console.WriteLine(nonRep(s));
}
}
const MAX_CHAR = 26;
function nonRep(s) {
const freq = new Array(MAX_CHAR).fill(0);
for (let c of s) {
freq[c.charCodeAt(0) - 'a'.charCodeAt(0)]++;
}
// Find the first character with frequency 1
for (let c of s) {
if (freq[c.charCodeAt(0) - 'a'.charCodeAt(0)] === 1) {
return c;
}
}
return '$';
}
let s = "geeksforgeeks";
console.log(nonRep(s));
Output
f
[Efficient Approach 2] By Storing Indices (Single Traversal) – O(n) Time and O(MAX_CHAR ) Space
The above approach can be optimized using a single traversal of the string. The idea is to maintain a visited array of size MAX_CHAR initialized to -1, indicating no characters have been seen yet. Now, we iterate through the string:
- If a character is seen for the first time, its index is stored in the array.
- If the character is found again then its array value is set to -2 to represent this character is now repeating.
After the string traversal, traverse the visited array and check if value in the array is not equal to -1 or -2 (means, this character is not repeating). We then find the smallest positive index from these values to find the first non-repeating character. If no such index is found, return '$'.
#include <bits/stdc++.h>
using namespace std;
const int MAX_CHAR = 26;
char nonRep(const string& s) {
vector<int> vis(MAX_CHAR, -1);
for (int i = 0; i < s.length(); ++i) {
int index = s[i] - 'a';
if (vis[index] == -1) {
// Store the index when character is first seen
vis[index] = i;
} else {
// Mark character as repeated
vis[index] = -2;
}
}
int idx = -1;
// Find the smallest index of the non-repeating characters
for (int i = 0; i < MAX_CHAR; ++i) {
if (vis[i] >= 0 && (idx == -1 || vis[i] < vis[idx])) {
idx = i;
}
}
return (idx == -1) ? '$' : s[vis[idx]];
}
int main() {
string s = "aabbccc";
cout << nonRep(s) << endl;
return 0;
}
import java.util.*;
public class Main {
static final int MAX_CHAR = 26;
public static char nonRep(String s) {
int[] vis = new int[MAX_CHAR];
Arrays.fill(vis, -1);
for (int i = 0; i < s.length(); i++) {
int index = s.charAt(i) - 'a';
if (vis[index] == -1) {
// Store the index when character is first seen
vis[index] = i;
} else {
// Mark character as repeated
vis[index] = -2;
}
}
int idx = -1;
// Find the smallest index of the non-repeating characters
for (int i = 0; i < MAX_CHAR; i++) {
if (vis[i] >= 0 && (idx == -1 || vis[i] < vis[idx])) {
idx = i;
}
}
return (idx == -1) ? '$' : s.charAt(vis[idx]);
}
public static void main(String[] args) {
String s = "aabbccc";
System.out.println(nonRep(s));
}
}
def nonRep(s):
MAX_CHAR = 26
vis = [-1] * MAX_CHAR
for i in range(len(s)):
index = ord(s[i]) - ord('a')
if vis[index] == -1:
# Store the index when character is first seen
vis[index] = i
else:
# Mark character as repeated
vis[index] = -2
idx = -1
# Find the smallest index of the non-repeating characters
for i in range(MAX_CHAR):
if vis[i] >= 0 and (idx == -1 or vis[i] < vis[idx]):
idx = i
return '$' if idx == -1 else s[vis[idx]]
s = "aabbccc"
print(nonRep(s))
using System;
class GFG
{
const int MAX_CHAR = 26;
static char nonRep(string s)
{
int[] vis = new int[MAX_CHAR];
Array.Fill(vis, -1);
for (int i = 0; i < s.Length; i++)
{
int index = s[i] - 'a';
if (vis[index] == -1)
{
// Store the index when character is first seen
vis[index] = i;
}
else
{
// Mark character as repeated
vis[index] = -2;
}
}
int idx = -1;
// Find the smallest index of the non-repeating characters
for (int i = 0; i < MAX_CHAR; i++)
{
if (vis[i] >= 0 && (idx == -1 || vis[i] < vis[idx]))
{
idx = i;
}
}
return idx == -1 ? '$' : s[vis[idx]];
}
static void Main()
{
string s = "aabbccc";
Console.WriteLine(nonRep(s));
}
}
function nonRep(s) {
const MAX_CHAR = 26;
let vis = new Array(MAX_CHAR).fill(-1);
for (let i = 0; i < s.length; i++) {
let index = s.charCodeAt(i) - 'a'.charCodeAt(0);
if (vis[index] === -1) {
// Store the index when character is first seen
vis[index] = i;
} else {
// Mark character as repeated
vis[index] = -2;
}
}
let idx = -1;
// Find the smallest index of the non-repeating characters
for (let i = 0; i < MAX_CHAR; i++) {
if (vis[i] >= 0 && (idx === -1 || vis[i] < vis[idx])) {
idx = i;
}
}
return idx === -1 ? '$' : s[vis[idx]];
}
let s = "aabbccc";
console.log(nonRep(s));
Output
$