First nonrepeating character in a stream (original) (raw)
First non-repeating character in a stream
Last Updated : 25 Mar, 2025
Given an input stream s
consisting solely of lowercase letters, you are required to identify which character has appeared only once in the stream up to each point. If there are multiple characters that have appeared only once, return the one that first appeared. If no character has appeared only once, append '#' to the result.
**Note: For each index i
(0 <= i < n), you need to determine the result considering the substring from the start of the stream up to the i
-th character.
**Examples:
**Input: s = "aabc"
**Output: "a#bb"
**Explanation: For every ith character we will consider the string from index 0 till index i first non repeating character is as follow- "a" - first non-repeating character is 'a' "aa" - no non-repeating character so '#' "aab" - first non-repeating character is 'b' "aabc" - there are two non repeating characters 'b' and 'c', first non-repeating character is 'b' because 'b' comes before 'c' in the stream.**Input: s = "bb"
**Output: "b#"
**Explanation: For every character first non repeating character is as follow- "b" - first non-repeating character is 'b' "bb" - no non-repeating character so '#'
Table of Content
- [Naive Approach] Using Nested Loop - O(n^2) time and O(n) space
- [Better Approach - 1] Using Queue and Unordered Map - O(n) time and O(n) space
- [Better Approach - 2] Using Queue and Frequency Array - O(n) time and O(n) space
- [Expected Approach] Using Frequency and Last Occurrence Array- O(n) time and O(1) space
**[Naive Approach] Using Nested Loop - O(n^2) time and O(n) space
This approach maintains a frequency count of each character using a vector. For each character in the string, it scans from the beginning to find the first non-repeating character by checking the frequency of each character up to that point. If a non-repeating character is found, it is appended to the result; otherwise,
#
is appended when no such character exists. This process ensures that the first non-repeating character is identified at each step.
C++ `
#include #include #include using namespace std;
string firstNonRepeating(const string &s) { string ans; int n = s.size();
// frequency vector for all ASCII characters
vector<int> freq(26, 0);
// Process each character in the stream
for (int i = 0; i < n; i++)
{
// Update frequency for the current character
freq[s[i]]++;
// Scan from the beginning to find the first non-repeating character
bool found = false;
for (int j = 0; j <= i; j++)
{
if (freq[s[j]] == 1)
{
ans.push_back(s[j]);
found = true;
break;
}
}
if (!found)
{
ans.push_back('#');
}
}
return ans;
}
int main() { string s = "aabc"; string ans = firstNonRepeating(s); cout << ans << endl; return 0; }
Java
import java.util.HashMap; import java.util.LinkedList; import java.util.Map;
public class GfG { public static String firstNonRepeating(String s) { StringBuilder ans = new StringBuilder(); int n = s.length();
// frequency map for all characters
Map<Character, Integer> freq = new HashMap<>();
// Process each character in the stream
for (int i = 0; i < n; i++) {
// Update frequency for the current character
freq.put(s.charAt(i), freq.getOrDefault(s.charAt(i), 0) + 1);
// Scan from the beginning to find the first non-repeating character
boolean found = false;
for (int j = 0; j <= i; j++) {
if (freq.get(s.charAt(j)) == 1) {
ans.append(s.charAt(j));
found = true;
break;
}
}
if (!found) {
ans.append('#');
}
}
return ans.toString();
}
public static void main(String[] args) {
String s = "aabc";
String ans = firstNonRepeating(s);
System.out.println(ans);
}
}
Python
def firstNonRepeating(s): ans = "" n = len(s)
# frequency dictionary for all characters
freq = [0] * 26
# Process each character in the stream
for i in range(n):
# Update frequency for the current character
freq[ord(s[i]) - ord('a')] += 1
# Scan from the beginning to find the first non-repeating character
found = False
for j in range(i + 1):
if freq[ord(s[j]) - ord('a')] == 1:
ans += s[j]
found = True
break
if not found:
ans += '#'
return ans
s = "aabc" ans = firstNonRepeating(s) print(ans)
C#
using System; using System.Collections.Generic;
class GfG { static string FirstNonRepeating(string s) { string ans = ""; int n = s.Length;
// frequency dictionary for all characters
Dictionary<char, int> freq = new Dictionary<char, int>();
// Process each character in the stream
for (int i = 0; i < n; i++) {
// Update frequency for the current character
if (freq.ContainsKey(s[i]))
freq[s[i]]++;
else
freq[s[i]] = 1;
// Scan from the beginning to find the first non-repeating character
bool found = false;
for (int j = 0; j <= i; j++) {
if (freq[s[j]] == 1) {
ans += s[j];
found = true;
break;
}
}
if (!found) {
ans += '#';
}
}
return ans;
}
static void Main()
{
string s = "aabc";
string ans = FirstNonRepeating(s);
Console.WriteLine(ans);
}
}
JavaScript
function firstNonRepeating(s) { let ans = ''; let n = s.length;
// frequency object for all characters
let freq = {};
// Process each character in the stream
for (let i = 0; i < n; i++) {
// Update frequency for the current character
freq[s[i]] = (freq[s[i]] || 0) + 1;
// Scan from the beginning to find the first non-repeating character
let found = false;
for (let j = 0; j <= i; j++) {
if (freq[s[j]] === 1) {
ans += s[j];
found = true;
break;
}
}
// If no non-repeating character exists so far, append '#'
if (!found) {
ans += '#';
}
}
return ans;
}
let s = "aabc"; let ans = firstNonRepeating(s); console.log(ans);
`
[Better Approach - 1] Using Queue and Unordered Map - O(n) time and O(n) space
This problem can be solved using queue, push into the queue every time when unique character is found and **pop it out when you get front character of queue repeated in the stream , this is how first non-repeated character in managed.
Follow the below steps to solve the given problem:
- Take **map to check the uniqueness of an element.
- Take **queue to find first non-repeating element.
- Traverse through the string and increase the count of elements in map and **push in to **queue is count is 1.
- If count of **front element of the queue > 1 anytime then **pop it from the queue until we get unique element at the **front.
- If **queue is empty anytime append **answer string with '#' else append it with **front element of queue.
- return **answer string. C++ `
#include <bits/stdc++.h> using namespace std;
string firstNonRepeating(string s) { string ans = "";
unordered_map<char, int> mp;
queue<char> q;
// queue to keep non-repeating element at the front.
for (int i = 0; i < s.length(); i++)
{
// if non-repeating element found push it in queue and count in map
if (mp.find(s[i]) == mp.end())
{
q.push(s[i]);
}
mp[s[i]]++;
// if anytime front element is repeating pop it from queue
while (!q.empty() && mp[q.front()] > 1)
{
q.pop();
}
// if queue is not empty append front element else append "#" in ans string.
if (!q.empty())
{
ans += q.front();
}
else
{
ans += '#';
}
}
return ans;
}
int main() { string s = "aabc"; string ans = firstNonRepeating(s); cout << ans << "\n"; return 0; }
Java
import java.util.*;
class Solution { public String firstNonRepeating(String s) { StringBuilder ans = new StringBuilder();
HashMap<Character, Integer> mp = new HashMap<>();
Queue<Character> q = new LinkedList<>();
for (int i = 0; i < s.length(); i++) {
// if non-repeating element found push it in queue and count in map
if (!mp.containsKey(s.charAt(i))) {
q.offer(s.charAt(i));
}
mp.put(s.charAt(i), mp.getOrDefault(s.charAt(i), 0) + 1);
// if anytime front element is repeating pop it from queue
while (!q.isEmpty() && mp.get(q.peek()) > 1) {
q.poll();
}
// if queue is not empty append front element else append "#" in ans string.
if (!q.isEmpty()) {
ans.append(q.peek());
} else {
ans.append('#');
}
}
return ans.toString();
}
public static void main(String[] args) {
String s = "aabc";
Solution sol = new Solution();
String ans = sol.firstNonRepeating(s);
System.out.println(ans);
}
}
Python
from collections import defaultdict, deque
def firstNonRepeating(s): ans = ""
mp = defaultdict(int)
q = deque()
for char in s:
# if non-repeating element found push it in queue and count in map
if mp[char] == 0:
q.append(char)
mp[char] += 1
# if anytime front element is repeating pop it from queue
while q and mp[q[0]] > 1:
q.popleft()
# if queue is not empty append front element else append '#' in ans string.
if q:
ans += q[0]
else:
ans += '#'
return ans
if name == 'main': s = "aabc" ans = firstNonRepeating(s) print(ans)
C#
using System; using System.Collections.Generic; using System.Linq;
class GfG { static string FirstNonRepeating(string s) { string ans = "";
Dictionary<char, int> mp = new Dictionary<char, int>();
Queue<char> q = new Queue<char>();
foreach (char c in s)
{
// if non-repeating element found push it in queue and count in map
if (!mp.ContainsKey(c))
{
q.Enqueue(c);
}
mp[c] = mp.ContainsKey(c) ? mp[c] + 1 : 1;
// if anytime front element is repeating pop it from queue
while (q.Count > 0 && mp[q.Peek()] > 1)
{
q.Dequeue();
}
// if queue is not empty append front element else append "#" in ans string.
if (q.Count > 0)
{
ans += q.Peek();
}
else
{
ans += '#';
}
}
return ans;
}
static void Main()
{
string s = "aabc";
string ans = FirstNonRepeating(s);
Console.WriteLine(ans);
}
}
JavaScript
function firstNonRepeating(s) { let ans = '';
const mp = {};
const q = [];
for (let i = 0; i < s.length; i++) {
// if non-repeating element found push it in queue and count in map
if (!mp[s[i]]) {
q.push(s[i]);
}
mp[s[i]] = (mp[s[i]] || 0) + 1;
// if anytime front element is repeating pop it from queue
while (q.length > 0 && mp[q[0]] > 1) {
q.shift();
}
// if queue is not empty append front element else append '#' in ans string.
if (q.length > 0) {
ans += q[0];
} else {
ans += '#';
}
}
return ans;
}
const s = 'aabc'; const ans = firstNonRepeating(s); console.log(ans);
`
[Better Approach - 2] Using Queue and Frequency Array - O(n) time and O(n) space
The idea is to maintain a count array of size 26 to keep track of the frequency of each character in the input stream. We also use a queue to store the characters in the input stream and maintain the order of their appearance.
Follow the steps below to implement above idea:
- Create a count array of size 26 to store the frequency of each character.
- Create a queue to store the characters in the input stream.
- Initialize an empty string as the answer.
- For each character in the input stream, add it to the queue and increment its frequency in the count array.
- While the queue is not empty, check if the frequency of the front character in the queue is 1.
- If the frequency is 1, append the character to the answer. If the frequency is greater than 1, remove the front character from the queue.
- If there are no characters left in the queue, append '#' to the answer. C++ `
#include <bits/stdc++.h> using namespace std;
string firstNonRepeating(string s) { string ans = "";
vector<int> count(26, 0);
queue<char> q;
for (int i = 0; i < s.length(); i++) {
// if non-repeating element found push it in queue
if (count[s[i] - 'a'] == 0) {
q.push(s[i]);
}
count[s[i] - 'a']++;
// if front element is repeating pop it from the queue
while (!q.empty() && count[q.front() - 'a'] > 1) {
q.pop();
}
// if queue is not empty append front element else append "#" in ans string.
if (!q.empty()) {
ans += q.front();
}
else {
ans += '#';
}
}
return ans;
}
int main()
{
string s = "aabc";
string ans = firstNonRepeating(s);
cout << ans << "\n";
return 0;
}
Java
import java.util.*;
class Solution { public String firstNonRepeating(String s) { StringBuilder ans = new StringBuilder(); int[] count = new int[26]; Queue q = new LinkedList<>();
for (int i = 0; i < s.length(); i++) {
// if non-repeating element found push it in queue
if (count[s.charAt(i) - 'a'] == 0) {
q.add(s.charAt(i));
}
count[s.charAt(i) - 'a']++;
// if front element is repeating pop it from the queue
while (!q.isEmpty() && count[q.peek() - 'a'] > 1) {
q.poll();
}
// if queue is not empty append front element else append "#" in ans string.
if (!q.isEmpty()) {
ans.append(q.peek());
} else {
ans.append('#');
}
}
return ans.toString();
}
public static void main(String[] args) {
Solution solution = new Solution();
String s = "aabc";
String ans = solution.firstNonRepeating(s);
System.out.println(ans);
}
}
Python
from collections import deque
def firstNonRepeating(s): ans = "" count = [0] * 26 q = deque()
for char in s:
# if non-repeating element found push it in queue
if count[ord(char) - ord('a')] == 0:
q.append(char)
count[ord(char) - ord('a')] += 1
# if front element is repeating pop it from the queue
while q and count[ord(q[0]) - ord('a')] > 1:
q.popleft()
# if queue is not empty append front element else append "#" in ans string.
if q:
ans += q[0]
else:
ans += '#'
return ans
if name == 'main': s = "aabc" ans = firstNonRepeating(s) print(ans)
C#
using System; using System.Collections.Generic;
class Solution { public string FirstNonRepeating(string s) { string ans = ""; int[] count = new int[26]; Queue q = new Queue();
foreach (char c in s) {
// if non-repeating element found push it in queue
if (count[c - 'a'] == 0) {
q.Enqueue(c);
}
count[c - 'a']++;
// if front element is repeating pop it from the queue
while (q.Count > 0 && count[q.Peek() - 'a'] > 1) {
q.Dequeue();
}
// if queue is not empty append front element else append "#" in ans string.
if (q.Count > 0) {
ans += q.Peek();
} else {
ans += '#';
}
}
return ans;
}
static void Main() {
Solution solution = new Solution();
string s = "aabc";
string ans = solution.FirstNonRepeating(s);
Console.WriteLine(ans);
}
}
JavaScript
// Function to find the first non-repeating character in a string function firstNonRepeating(s) { let ans = ""; let count = new Array(26).fill(0); let q = [];
for (let i = 0; i < s.length; i++) {
// if non-repeating element found push it in queue
if (count[s.charCodeAt(i) - 'a'.charCodeAt(0)] === 0) {
q.push(s[i]);
}
count[s.charCodeAt(i) - 'a'.charCodeAt(0)]++;
// if front element is repeating pop it from the queue
while (q.length > 0 && count[q[0].charCodeAt(0) - 'a'.charCodeAt(0)] > 1) {
q.shift();
}
// if queue is not empty append front element else append "#" in ans string.
if (q.length > 0) {
ans += q[0];
} else {
ans += '#';
}
}
return ans;
}
let s = "aabc"; let ans = firstNonRepeating(s); console.log(ans);
`
[Expected Approach] Using Frequency and Last Occurrence Array- O(n) time and O(1) space
The approach tracks the frequency of each character and its last occurrence index in the string. In the first pass, we store the last occurrence of each character, and in the second pass, we check the frequency of each character to find the first non-repeating character. The solution efficiently determines the first non-repeating character by using the frequency and last occurrence arrays, ensuring a fast result even as the string grows in size.
C++ `
#include #include using namespace std;
string firstNonRepeating(string &s) { int n = s.size();
// Frequency array
vector<int> f(26, 0);
// Last occurrence array
vector<int> last(26, -1);
// Update last occurrence of each character
for (int i = 0; i < n; i++) {
if (last[s[i] - 'a'] == -1)
last[s[i] - 'a'] = i;
}
string ans = "";
// Find the first non-repeating character
for (int i = 0; i < n; i++) {
f[s[i] - 'a']++;
char ch = '#';
int x = n + 1;
// Find the first non-repeating character
// based on frequency and last occurrence
for (int j = 0; j < 26; j++) {
if (f[j] == 1 && x > last[j]) {
ch = char(j + 'a');
x = last[j];
}
}
ans += ch;
}
return ans;
}
int main() {
string s = "aabc";
string ans = firstNonRepeating(s);
cout << ans << endl;
return 0;
}
Java
import java.util.*;
public class Main { public static String firstNonRepeating(String s) { int n = s.length();
// Frequency array
int[] f = new int[26];
// Last occurrence array
int[] last = new int[26];
Arrays.fill(last, -1);
// Update last occurrence of each character
for (int i = 0; i < n; i++) {
if (last[s.charAt(i) - 'a'] == -1)
last[s.charAt(i) - 'a'] = i;
}
StringBuilder ans = new StringBuilder();
// Find the first non-repeating character
for (int i = 0; i < n; i++) {
f[s.charAt(i) - 'a']++;
char ch = '#';
int x = n + 1;
// Find the first non-repeating character
// based on frequency and last occurrence
for (int j = 0; j < 26; j++) {
if (f[j] == 1 && x > last[j]) {
ch = (char)(j + 'a');
x = last[j];
}
}
ans.append(ch);
}
return ans.toString();
}
public static void main(String[] args) {
String s = "aabc";
String ans = firstNonRepeating(s);
System.out.println(ans);
}
}
Python
def first_non_repeating(s): n = len(s) # Frequency array f = [0] * 26 # Last occurrence array last = [-1] * 26
# Update last occurrence of each character
for i in range(n):
if last[ord(s[i]) - ord('a')] == -1:
last[ord(s[i]) - ord('a')] = i
ans = ""
# Find the first non-repeating character
for i in range(n):
f[ord(s[i]) - ord('a')] += 1
ch = '#'
x = n + 1
# Find the first non-repeating character
# based on frequency and last occurrence
for j in range(26):
if f[j] == 1 and x > last[j]:
ch = chr(j + ord('a'))
x = last[j]
ans += ch
return ans
s = "aabc" ans = first_non_repeating(s) print(ans)
C#
using System; using System.Collections.Generic;
class Program { public static string FirstNonRepeating(string s) { int n = s.Length;
// Frequency array
int[] f = new int[26];
// Last occurrence array
int[] last = new int[26];
Array.Fill(last, -1);
// Update last occurrence of each character
for (int i = 0; i < n; i++) {
if (last[s[i] - 'a'] == -1)
last[s[i] - 'a'] = i;
}
string ans = "";
// Find the first non-repeating character
for (int i = 0; i < n; i++) {
f[s[i] - 'a']++;
char ch = '#';
int x = n + 1;
// Find the first non-repeating character based
// on frequency and last occurrence
for (int j = 0; j < 26; j++) {
if (f[j] == 1 && x > last[j]) {
ch = (char)(j + 'a');
x = last[j];
}
}
ans += ch;
}
return ans;
}
static void Main() {
string s = "aabc";
string ans = FirstNonRepeating(s);
Console.WriteLine(ans);
}
}
JavaScript
function firstNonRepeating(s) { let n = s.length;
// Frequency array
let f = new Array(26).fill(0);
// Last occurrence array
let last = new Array(26).fill(-1);
// Update last occurrence of each character
for (let i = 0; i < n; i++) {
if (last[s.charCodeAt(i) - 'a'.charCodeAt(0)] === -1)
last[s.charCodeAt(i) - 'a'.charCodeAt(0)] = i;
}
let ans = '';
// Find the first non-repeating character
for (let i = 0; i < n; i++) {
f[s.charCodeAt(i) - 'a'.charCodeAt(0)]++;
let ch = '#';
let x = n + 1;
// Find the first non-repeating character based
// on frequency and last occurrence
for (let j = 0; j < 26; j++) {
if (f[j] === 1 && x > last[j]) {
ch = String.fromCharCode(j + 'a'.charCodeAt(0));
x = last[j];
}
}
ans += ch;
}
return ans;
}
let s = 'aabc'; let ans = firstNonRepeating(s); console.log(ans);
`