First nonrepeating character in a stream (original) (raw)

First non-repeating character in a stream

Last Updated : 25 Mar, 2025

Try it on GfG Practice redirect icon

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

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:

#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:

#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);

`