First Non Repeating Character For Every Prefix

Last Updated : 16 Oct, 2026

Given a string s consisting of only lowercase alphabets, for each index i in the string (0 ≤ i < n), find the first non-repeating character in the prefix s[0..i]. If no such character exists, use '#'.

Examples:

Input: s = "aabc"
Output: a#bb
Explanation:
At i=0 ("a"): First non-repeating character is 'a'.
At i=1 ("aa"): No non-repeating character, so '#'.
At i=2 ("aab"): First non-repeating character is 'b'.
At i=3 ("aabc"): Non-repeating characters are 'b' and 'c'; 'b' appeared first, so 'b'.

Input: s = "bb"
Output: "b#"
Explanation:
At i=0 ("b"): First non-repeating character is 'b'.
At i=1 ("bb"): No non-repeating character, so '#'.

Try It Yourself
redirect icon

[Naive Approach] Nested Loop - O(n ^ 2) time and O(n) space

The idea is to use a frequency array to count character occurrences and scan the processed part of the string to find the first non-repeating character.

  • Update the frequency of the current character.
  • Scan from the beginning and append the first character with frequency 1; if none exists, append '#'.
  • Repeat for each character and return the result.
C++
#include <iostream>
#include <string>
#include <vector>
using namespace std;

string firstNonRepeating(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] - 'a']++;

        // 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] - 'a'] == 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
class GFG {
    static String firstNonRepeating(String s)
    {
        StringBuilder ans = new StringBuilder();
        int n = s.length();

        // frequency array for all ASCII characters
        int[] freq = new int[26];

        // Process each character in the stream
        for (int i = 0; i < n; i++) {

            // Update frequency for the current character
            freq[s.charAt(i) - 'a']++;

            // Scan from the beginning to find the
            // first non-repeating character
            boolean found = false;

            for (int j = 0; j <= i; j++) {
                if (freq[s.charAt(j) - 'a'] == 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 list for all ASCII 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

if __name__ == "__main__":
    s = "aabc"
    ans = firstNonRepeating(s)
    print(ans)
C#
using System;
using System.Text;

class GFG {
    static string firstNonRepeating(string s)
    {
        StringBuilder ans = new StringBuilder();
        int n = s.Length;

        // frequency array for all ASCII characters
        int[] freq = new int[26];

        // Process each character in the stream
        for (int i = 0; i < n; i++) {
            // Update frequency for the current character
            freq[s[i] - 'a']++;

            // 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] - 'a'] == 1) {
                    ans.Append(s[j]);
                    found = true;
                    break;
                }
            }

            if (!found) {
                ans.Append('#');
            }
        }

        return ans.ToString();
    }

    public static void Main()
    {
        string s = "aabc";
        string ans = firstNonRepeating(s);
        Console.WriteLine(ans);
    }
}
JavaScript
function firstNonRepeating(s)
{
    let ans = "";
    let n = s.length;

    // frequency array for all ASCII characters
    let freq = new Array(26).fill(0);

    // Process each character in the stream
    for (let i = 0; i < n; i++) {

        // Update frequency for the current character
        freq[s.charCodeAt(i) - "a".charCodeAt(0)]++;

        // Scan from the beginning to find the first
        // non-repeating character
        let found = false;

        for (let j = 0; j <= i; j++) {
            if (freq[s.charCodeAt(j) - "a".charCodeAt(0)]
                === 1) {
                ans += s[j];
                found = true;
                break;
            }
        }

        if (!found) {
            ans += "#";
        }
    }

    return ans;
}

// Driver Code
let s = "aabc";
let ans = firstNonRepeating(s);
console.log(ans);

Output
a#bb

[Better Approach] Queue and Frequency Array - O(n) Time and O(n) Space

The idea is to use a frequency array to track character occurrences and a queue to maintain characters in their order of appearance.

  • For each character, update its frequency and remove repeating characters from the front of the queue.
  • If the queue is not empty, append its front character to the result; otherwise, append '#'.
  • Return the result after processing all characters.
C++
#include <iostream>
#include <queue>
#include <vector>
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.LinkedList;
import java.util.Queue;

class GFG {
    static String firstNonRepeating(String s)
    {
        StringBuilder ans = new StringBuilder();
        int[] count = new int[26];

        Queue<Character> 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)
    {
        String s = "aabc";
        String ans = 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;
using System.Text;

class GFG {
    string firstNonRepeating(string s)
    {
        StringBuilder ans = new StringBuilder();
        int[] count = new int[26];
        Queue<char> q = new Queue<char>();

        for (int i = 0; i < s.Length; i++) {
            if (count[s[i] - 'a'] == 0)
                q.Enqueue(s[i]);

            count[s[i] - 'a']++;

            while (q.Count > 0 && count[q.Peek() - 'a'] > 1)
                q.Dequeue();

            if (q.Count > 0)
                ans.Append(q.Peek());
            else
                ans.Append('#');
        }

        return ans.ToString();
    }

    public static void Main()
    {
        string s = "aabc";
        GFG obj = new GFG();
        Console.WriteLine(obj.firstNonRepeating(s));
    }
}
JavaScript
// Node class for doubly linked list
class Node {
    constructor(data)
    {
        this.data = data;
        this.prev = null;
        this.next = null;
    }
}

// Queue implemented using doubly linked list
class Queue {
    constructor()
    {
        this.front = null;
        this.rear = null;
        this.size = 0;
    }

    // Add element at the rear
    enqueue(x)
    {
        let node = new Node(x);
        if (!this.rear) {
            this.front = this.rear = node;
        }
        else {
            node.prev = this.rear;
            this.rear.next = node;
            this.rear = node;
        }
        this.size++;
    }

    // Remove element from the front
    dequeue()
    {
        if (!this.front) {
            console.log("Queue is empty");
            return null;
        }
        let val = this.front.data;
        this.front = this.front.next;
        if (this.front)
            this.front.prev = null;
        else
            this.rear = null;
        this.size--;
        return val;
    }

    // Get front element without removing
    frontElement()
    {
        return this.front ? this.front.data : null;
    }

    isEmpty() { return this.size === 0; }
}

// Function to find first non-repeating character in a
// stream
function firstNonRepeating(s)
{
    let ans = "";
    let count = new Array(26).fill(0);
    let q = new Queue();

    for (let i = 0; i < s.length; i++) {
        let idx = s.charCodeAt(i) - "a".charCodeAt(0);

        // if first occurrence, enqueue it
        if (count[idx] === 0) {
            q.enqueue(s[i]);
        }
        count[idx]++;

        // remove repeating elements from front
        while (!q.isEmpty()
               && count[q.frontElement().charCodeAt(0)
                        - "a".charCodeAt(0)]
                      > 1) {
            q.dequeue();
        }

        // append first non-repeating or '#' if none
        ans += q.isEmpty() ? "#" : q.frontElement();
    }

    return ans;
}

// Driver code
let s = "aabc";
let ans = firstNonRepeating(s);
console.log(ans);

Output
a#bb

[Expected Approach] Frequency and First Occurrence Arrays – O(26 * n) Time and O(1) Space

The idea is to maintain a frequency array to count character occurrences and another array to store the first position of each character.

  • While traversing the string, we update the frequency of each character and find the character with frequency 1 that appeared earliest.
  • If no such character exists, we append '#' to the result.
C++
#include <iostream>
#include <vector>
using namespace std;

string firstNonRepeating(string &s)
{
    int n = s.size();
    vector<int> freq(26, 0);
    vector<int> firstPos(26, -1);

    // record first occurrence for each character
    for (int i = 0; i < n; i++)
    {
        if (firstPos[s[i] - 'a'] == -1)
            firstPos[s[i] - 'a'] = i;
    }

    string result = "";
    for (int i = 0; i < n; i++)
    {
        freq[s[i] - 'a']++;

        char chosen = '#';
        int earliest = n + 1;

        // find earliest character with frequency 1
        for (int j = 0; j < 26; j++)
        {
            if (freq[j] == 1 && earliest > firstPos[j])
            {
                chosen = char(j + 'a');
                earliest = firstPos[j];
            }
        }
        result += chosen;
    }

    return result;
}

int main()
{
    string s = "aabc";
    cout << firstNonRepeating(s) << endl;
    return 0;
}
Java
class GFG {
    static String firstNonRepeating(String s)
    {
        int n = s.length();
        int[] freq = new int[26];
        int[] firstPos = new int[26];
        for (int i = 0; i < 26; i++)
            firstPos[i] = -1;

        // record first occurrence for each character
        for (int i = 0; i < n; i++) {
            int idx = s.charAt(i) - 'a';
            if (firstPos[idx] == -1)
                firstPos[idx] = i;
        }

        StringBuilder result = new StringBuilder();

        for (int i = 0; i < n; i++) {
            int idx = s.charAt(i) - 'a';
            freq[idx]++;

            char chosen = '#';
            int earliest = n + 1;

            // find earliest character with frequency 1
            for (int j = 0; j < 26; j++) {
                if (freq[j] == 1
                    && firstPos[j] < earliest) {
                    chosen = (char)(j + 'a');
                    earliest = firstPos[j];
                }
            }

            result.append(chosen);
        }

        return result.toString();
    }

    public static void main(String[] args)
    {
        String s = "aabc";
        System.out.println(firstNonRepeating(s));
    }
}
Python
def firstNonRepeating(s):
    n = len(s)
    freq = [0] * 26
    firstPos = [-1] * 26
    
    # record first occurrence for each character
    for i in range(n):
        if firstPos[ord(s[i]) - ord('a')] == -1:
            firstPos[ord(s[i]) - ord('a')] = i

    result = ""
    for i in range(n):
        freq[ord(s[i]) - ord('a')] += 1

        chosen = '#'
        earliest = n + 1

        # find earliest character with frequency 1
        for j in range(26):
            if freq[j] == 1 and earliest > firstPos[j]:
                chosen = chr(j + ord('a'))
                earliest = firstPos[j]
        result += chosen

    return result

if __name__ == '__main__':
    s = "aabc"
    print(firstNonRepeating(s))
C#
using System;
using System.Text;

class GfG {
    static string firstNonRepeating(string s)
    {
        int n = s.Length;
        int[] freq = new int[26];
        int[] firstPos = new int[26];
        Array.Fill(firstPos, -1);

        // record first occurrence for each character
        for (int i = 0; i < n; i++) {
            if (firstPos[s[i] - 'a'] == -1)
                firstPos[s[i] - 'a'] = i;
        }

        StringBuilder result = new StringBuilder();
        for (int i = 0; i < n; i++) {
            freq[s[i] - 'a']++;

            char chosen = '#';
            int earliest = n + 1;

            // find earliest character with frequency 1
            for (int j = 0; j < 26; j++) {
                if (freq[j] == 1
                    && earliest > firstPos[j]) {
                    chosen = (char)(j + 'a');
                    earliest = firstPos[j];
                }
            }
            result.Append(chosen);
        }
        return result.ToString();
    }

    public static void Main()
    {
        string s = "aabc";
        Console.WriteLine(firstNonRepeating(s));
    }
}
JavaScript
function firstNonRepeating(s)
{
    let n = s.length;
    let freq = new Array(26).fill(0);
    let firstPos = new Array(26).fill(-1);

    // record first occurrence for each character
    for (let i = 0; i < n; i++) {
        if (firstPos[s.charCodeAt(i) - "a".charCodeAt(0)]
            === -1)
            firstPos[s.charCodeAt(i) - "a".charCodeAt(0)]
                = i;
    }

    let result = "";
    for (let i = 0; i < n; i++) {
        freq[s.charCodeAt(i) - "a".charCodeAt(0)]++;

        let chosen = "#";
        let earliest = n + 1;

        // find earliest character with frequency 1
        for (let j = 0; j < 26; j++) {
            if (freq[j] === 1 && earliest > firstPos[j]) {
                chosen = String.fromCharCode(
                    j + "a".charCodeAt(0));
                earliest = firstPos[j];
            }
        }
        result += chosen;
    }
    return result;
}

// Driver Code
let s = "aabc";
console.log(firstNonRepeating(s));

Output
a#bb
Comment