# Length of the longest substring without repeating characters

Given a string, find the length of the longest substring without repeating characters. For example, the longest substrings without repeating characters for “ABDEFGABEF” are “BDEFGA” and “DEFGAB”, with length 6. For “BBBB” the longest substring is “B”, with length 1. For “GEEKSFORGEEKS”, there are two longest substrings shown in the below diagrams, with length 7.

The desired time complexity is O(n) where n is the length of the string.

Method 1 (Simple)
We can consider all substrings one by one and check for each substring whether it contains all unique characters or not. There will be n*(n+1)/2 substrings. Whether a substirng contains all unique characters or not can be checked in linear time by scanning it from left to right and keeping a map of visited characters. Time complexity of this solution would be O(n^3).

Method 2 (Linear Time)
Let us talk about the linear time solution now. This solution uses extra space to store the last indexes of already visited characters. The idea is to scan the string from left to right, keep track of the maximum length Non-Repeating Character Substring (NRCS) seen so far. Let the maximum length be max_len. When we traverse the string, we also keep track of length of the current NRCS using cur_len variable. For every new character, we look for it in already processed part of the string (A temp array called visited[] is used for this purpose). If it is not present, then we increase the cur_len by 1. If present, then there are two cases:

a) The previous instance of character is not part of current NRCS (The NRCS which is under process). In this case, we need to simply increase cur_len by 1.
b) If the previous instance is part of the current NRCS, then our current NRCS changes. It becomes the substring staring from the next character of previous instance to currently scanned character. We also need to compare cur_len and max_len, before changing current NRCS (or changing cur_len).

Implementation

## C/C++

```// C/C++ program to find the length of the longest substring
// without repeating characters
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#define NO_OF_CHARS 256

int min(int a, int b);

int longestUniqueSubsttr(char *str)
{
int n = strlen(str);
int cur_len = 1;  // lenght of current substring
int max_len = 1;  // result
int prev_index;  //  previous index
int i;
int *visited = (int *)malloc(sizeof(int)*NO_OF_CHARS);

/* Initialize the visited array as -1, -1 is used to
indicate that character has not been visited yet. */
for (i = 0; i < NO_OF_CHARS;  i++)
visited[i] = -1;

/* Mark first character as visited by storing the index
of first   character in visited array. */
visited[str[0]] = 0;

/* Start from the second character. First character is
already processed (cur_len and max_len are initialized
as 1, and visited[str[0]] is set */
for (i = 1; i < n; i++)
{
prev_index =  visited[str[i]];

/* If the currentt character is not present in the
already processed substring or it is not part of
the current NRCS, then do cur_len++ */
if (prev_index == -1 || i - cur_len > prev_index)
cur_len++;

/* If the current character is present in currently
considered NRCS, then update NRCS to start from
the next character of previous instance. */
else
{
/* Also, when we are changing the NRCS, we
should also check whether length of the
previous NRCS was greater than max_len or
not.*/
if (cur_len > max_len)
max_len = cur_len;

cur_len = i - prev_index;
}

// update the index of current character
visited[str[i]] = i;
}

// Compare the length of last NRCS with max_len and
// update max_len if needed
if (cur_len > max_len)
max_len = cur_len;

free(visited); // free memory allocated for visited
return max_len;
}

/* A utility function to get the minimum of two integers */
int min(int a, int b)
{
return (a>b)?b:a;
}

/* Driver program to test above function */
int main()
{
char str[] = "ABDEFGABEF";
printf("The input string is %s \n", str);
int len =  longestUniqueSubsttr(str);
printf("The length of the longest non-repeating "
"character substring is %d", len);
return 0;
}
```

## Python

```# Python program to find the length of the longest substring
# without repeating characters
NO_OF_CHARS = 256

def longestUniqueSubsttr(string):
n = len(string)
cur_len = 1        # To store the lenght of current substring
max_len = 1        # To store the result
prev_index = 0    # To store the previous index
i = 0

# Initialize the visited array as -1, -1 is used to indicate
# that character has not been visited yet.
visited = [-1] * NO_OF_CHARS

# Mark first character as visited by storing the index of
# first character in visited array.
visited[ord(string[0])] = 0

# Start from the second character. First character is already
# processed (cur_len and max_len are initialized as 1, and
# visited[str[0]] is set
for i in xrange(1,n):
prev_index = visited[ord(string[i])]

# If the currentt character is not present in the already
# processed substring or it is not part of the current NRCS,
# then do cur_len++
if prev_index == -1 or (i - cur_len > prev_index):
cur_len+=1

# If the current character is present in currently considered
# NRCS, then update NRCS to start from the next character of
# previous instance.
else:
# Also, when we are changing the NRCS, we should also
# check whether length of the previous NRCS was greater
# than max_len or not.
if cur_len > max_len:
max_len = cur_len

cur_len = i - prev_index

# update the index of current character
visited[ord(string[i])] = i

# Compare the length of last NRCS with max_len and update
# max_len if needed
if cur_len > max_len:
max_len = cur_len

return max_len

# Driver program to test the above function
string = "ABDEFGABEF"
print "The input string is " + string
length = longestUniqueSubsttr(string)
print ("The length of the longest non-repeating character" +
" substring is " + str(length))

# This code is contributed by Bhavya Jain
```

Output

```  The input string is ABDEFGABEF
The length of the longest non-repeating character substring is 6
```

Time Complexity: O(n + d) where n is length of the input string and d is number of characters in input string alphabet. For example, if string consists of lowercase English characters then value of d is 26.
Auxiliary Space: O(d)

As an exercise, try the modified version of the above problem where you need to print the maximum length NRCS also (the above program only prints length of it).

• Arnab

package Geeks;

import java.lang.*;

import java.util.*;

class longestSubstr{

public static void main(String[] args){

String s=”ABDEFGABEF”;

int ans=calc(s);

System.out.println(“Max nonrepeating seq= “+ans);

}

public static int calc(String s)

{

int n=s.length();

int max=1;

if(n==1)

return 1;

if(n==2)

{

if(s.charAt(0)==s.charAt(1)) return 1;

else return 2;

}

String s1=s;

String a=s.charAt(n-1)+””;

s1=s1.replace(a,””);

// System.out.println(s+” “+(n-2)+” “+s.substring(0,n-1));

max=Math.max(calc(s.substring(0,n-1)),(calc(s1)+1));

return max;

}

}

• Ashish

The longest NRCS can be printed by code at below link:
http://ideone.com/FFQRkw

Plz point out if any mistake…….

• Mohaan

We can print and count like below.. If any mistake please specify…

http://ideone.com/IFZygQ

• Srikant Aggarwal

This is giving wrong answer for ABCDEFCGHIJB

• mccullum

its 9 correct

• shan

A very simple solution to check and find longest substring is

#include

using namespace std;

int main()

{

char s[]=”geeksforgeeks”;

bool visited[26]={false};

int max=INT_MIN,count=0,i=0;

while(s[i]!=”)

{

if(visited[s[i]-‘a’]==false)

{

visited[s[i]-‘a’]=true;

count++;

}

else{

memset(visited,false,sizeof(visited));

count=1;

visited[s[i]-‘a’]=true;

}

if(count>max)

max=count;

i++;

}

cout<<max;

return 0;

}

• prashant jha

here is the 0(nlogn) complexity using divide and conquer approach
http://ideone.com/eDWtc8

• Yogendra Singh Vimal

#include

#include

#include

#define MAX 256

int lsubstring(char *s)

{

int count[MAX][2]={{0}};

int MLEN=0,CLEN=0,i,j,ptr=0;

for(i=0;*(s+i);i++)

{

if(count[*(s+i)][0]==0)

{

count[*(s+i)][0]=1;

count[*(s+i)][1]=i;

CLEN++;

}

else

{

if(count[*(s+i)][1]>=ptr)

{

if(CLEN>MLEN)

MLEN=CLEN;

ptr=count[*(s+i)][1]+1;

CLEN=i-count[*(s+i)][1];

count[*(s+i)][1]=i;

}

else

{

count[*(s+i)][1]=i;

CLEN++;

}

}

}

return (CLEN>MLEN)?CLEN:MLEN;

}

int main()

{

char *s=”abcdaefghijklmnopqrstuvwxyz”;

printf(“nInput String is %s”,s);

int len=lsubstring(s);

printf(“nThe length of longest substring is %d”,len);

return 0;

}

• Harjit Singh

This is wrong. We have to use array of size equal to string size in stead of 256. It is giving wrong result.

• navneet goel

In the 2nd method program, run for the input string “geeksforkgeeks”. here it shows output as “The length of the longest non-repeating character substring is 7″ though here longest non repeating character substring is 5 (from k of geeks to k of fork).
Please correct me if i am wrong.

• chen

sforkge

• vikram

reposting….
Code for printing the longest unique sub string. Also prints all the unique strings of same length.
Please correct me, if something is wrong. Also please share if someone has better code.

``` #include "stdafx.h" #include <iostream> using namespace std; int LongestUniqueSubString(char *str) { if(str == 0) return 0; cout << "Input string = " << str << "n"; /*save the latest index at the character position*/ int charIdx[256]; for(int i=0; i = s) { if(e-s+1 == fc) { /*track equal longest unique strings*/ ++fi; fs[fi] = s; fe[fi] = e; }else if(e-s+1 > fc) { /*update longest unique string*/ fc=e-s+1; fs[0]=s; fe[0]=e; fi=0; } s = charIdx + 1; //move the start mark to next position. } charIdx = i; e=i; } if(e-s+1 == fc) { ++fi; fs[fi] = s; fe[fi] = e; }else if(e-s+1 > fc) { fc=e-s+1; fs[0]=s; fe[0]=e; fi=0; } cout << "The longest unique substring = n"; for(int i=0; i <= fi; i++) { for(int j=fs[i]; j <= fe[i]; j++) { cout << str[j]; } cout << "n"; } cout << "length = " << fc << "n"; cout << "-------------------------------------n"; return fc; } int _tmain(int argc, _TCHAR* argv[]) { char *p = "ABCDEFGH"; LongestUniqueSubString(p); p = "ABDEFGALMF"; LongestUniqueSubString(p); p = "GEEKSFORGEEKS"; LongestUniqueSubString(p); p = "AAAA"; LongestUniqueSubString(p); p = "ABCABCABC"; LongestUniqueSubString(p); p = "ABCDECQWERTYU"; LongestUniqueSubString(p); p = "BBACDBV"; LongestUniqueSubString(p); return 0; } ```

• vikram

``` Code for printing the longest unique sub strings. Please correct me, if something wrong. Please share, if someone has the code for printing the sub string. #include "stdafx.h" #include using namespace std; int LongestUniqueSubString(char *str) { if(str == 0) return 0; cout << "Input string = " << str << "n"; /*save the latest index at the character position*/ int charIdx[256]; for(int i=0; i = s) { if(e-s+1 == fc) { /*track equal longest unique strings*/ ++fi; fs[fi] = s; fe[fi] = e; }else if(e-s+1 > fc) { /*update longest unique string*/ fc=e-s+1; fs[0]=s; fe[0]=e; fi=0; } s = charIdx + 1; //move the start mark to next position. } charIdx = i; e=i; } if(e-s+1 == fc) { ++fi; fs[fi] = s; fe[fi] = e; }else if(e-s+1 > fc) { fc=e-s+1; fs[0]=s; fe[0]=e; fi=0; } cout << "The longest unique substring = n"; for(int i=0; i <= fi; i++) { for(int j=fs[i]; j <= fe[i]; j++) { cout << str[j]; } cout << "n"; } cout << "length = " << fc << "n"; cout << "-------------------------------------n"; return fc; } int _tmain(int argc, _TCHAR* argv[]) { char *p = "ABCDEFGH"; LongestUniqueSubString(p); p = "ABDEFGALMF"; LongestUniqueSubString(p); p = "GEEKSFORGEEKS"; LongestUniqueSubString(p); p = "AAAA"; LongestUniqueSubString(p); p = "ABCABCABC"; LongestUniqueSubString(p); p = "ABCDECQWERTYU"; LongestUniqueSubString(p); return 0; } ```

• vishal

O(n) time and O(26) space

``` ```
void initialise(int a[] , int n)
{
int i =0;
for(i = 0 ; i < n ;++i)
a[i]  = 0;
}
int main()
{
char arr[] = "GeeksforGeeks";
int count[26] = {0};
int i =0;
int max = 0 , sum = 0;
while( i < 13)
{
arr[i] = toupper(arr[i]);
if( count[arr[i] - 65] == 0)
{
++sum;
count[arr[i] -65] = 1;
}
else
{
if( sum > max)
max = sum;
sum = 0;
initialise(count , 26);
--i;
}

++i;
}
printf("The maximum : %d\n" , max);
return 0;
}

``` ```
• timus

try this as input: “asdfgauvwx”
It’ll give ans as 5, instead of 9

• vishal

O(n) solution with o(26) space

``` ```
void initialise(int a[] , int n)
{
int i =0;
for(i = 0 ; i < n ;++i)
a[i]  = 0;
}
int main()
{
char arr[] = "GeeksforGeeks";
int count[26] = {0};
int i =0;
int max = 0 , sum = 0;
while( i < 13)
{
arr[i] = toupper(arr[i]);
if( count[arr[i] - 65] == 0)
{
++sum;
count[arr[i] -65] = 1;
}
else
{
if( sum > max)
max = sum;
sum = 0;
initialise(count , 26);
--i;
}

++i;
}
printf("The maximum : %d\n" , max);
return 0;
}

``` ```
• Anonymous

Your algorithm fails for this case:
“GEEKSFORGEEKSXYZRLBHA”
Output is 7 but it should be 11
You should update max value every time new letter is added to NRCS

``` ```
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

void initialise(int a[] , int n)
{
int i =0;
for(i = 0 ; i < n ;++i)
a[i]  = 0;
}
int main()
{
char arr[] = "GEEKSFORGEEKSXYZRLBHA";
int count[26] = {0};
int i =0;
int max = 0 , sum = 0;
char n;
while( i < strlen(arr))
{
n = arr[i];
if( count[arr[i] - 65] == 0)
{
++sum;
count[arr[i] -65] = 1;
if( sum > max) max = sum;
}
else
{
if( sum > max) max = sum;
sum = 0;
initialise(count , 26);
--i;
}

++i;
}
printf("The maximum : %d\n" , max);
return 0;
}

``` ```
• vishal

Agreed I missed a case where the longest string is terminated at the end . Thank You for Pointing this out

``` ```

``` ```
• vivek

/*
#include
#include
void undo(int a[],char *s,int n)
{
int i;
for(i=0;i<=n;i++)
a[s[i]]=0;
}
int len(char *str)
{
int n =strlen(str);
int a[256]={0};
int i=0;
int maxcount=0;
int index=0;
int count=0;
while(i<n)
{
count=0;
while(!a[str[i]]&&i<n)
{
a[str[i]]++;
count++;
i++;
}
if(i!=n)
{
undo(a,str,i);index=i;
}
if(maxcount<count)
{
maxcount=count;
}
count=0;
}
printf("%c\n",str[index]);
return maxcount;
}
int main()
{

char s[]="ABCDEFGHIJAAKLMNOPQBARSTUVWXYZ";
printf("%d\n",len(s));
return 0;
}

*/

• The King

#include
#include
#define mchar 256

int main()
{
int i,j=0, len=0,max=0,*temp=NULL;
char str[20];
gets(str);

temp = (int *) calloc(sizeof(int) , mchar);

for(i=0;*(str+i);i++)
{
if(temp[*(str+i)] == 0)
{
len++;
temp[*(str+i)]=1;
}
else
{
for(j=len-1; j>=0 ; j–)
temp[*(str+j)] = 0;

temp[*(str+i)]=1;

if(len > max)
max = len;
len = 1;
}
}
printf(“The maximum substring is=%d”, max);
getchar();
return 0;
}

• me.abhinav

Another O(n) solution.
< >

``` ```
#include <iostream>
#define SIZ 100
#define index(c) c-'a'

using namespace std;

void process(char *str){
int i, j, start, end, maxLen = -1, curLen;
bool present[26];
for(i=0 ; i<26 ; i++)
present[i] = false;

present[index(str[0])] = true;
start = end = i = 0; curLen = j = 1;
while(str[j]){
if(!present[index(str[j])]){
curLen++;
}else{
while(present[index(str[j])]){
present[index(str[i])] = false;
i++;
curLen--;
}
}
if(curLen>maxLen){
maxLen = curLen;
start = i;
end = j;
}
present[index(str[j])] = true;
j++;
}
char *res = new char[end-start+2];
for(i=start ; i<=end ; i++)
res[i-start] = str[i];
res[i-start] = '\0';
cout<<start<<" "<<end<<" "<<res<<"\n\n";
}

int main(){
char str[SIZ];
char *res;

while(1){
cin>>str;
process(str);
}

return 0;
}

``` ```
• me.abhinav

EXPECTING ONLY LOWER CASE ENGLISH ALPHABETS

• pritybhudolia

I think this program is very simple and works in O(n) Complexity. I have used hashing.Correct me if anything is wrong.

#include
#include
int longestUniqueSubsttr(char str[])
{
int hash[256]={0};
int start=0,max=0,i=0,j=0,end=0,begin=0;
for(i=0;imax)
{
max=end-start;
begin=start;
j=end;

}
}
hash[str[i]]=1;
}
printf(“The longest non-repeating character substring is :”);
for(start=begin;start<=j;start++) printf(“%c”,str[start]); return max; } int main() { char str[] = “GEEKSFORGEEKS”; printf(“The input string is :%s \n”, str); int len = longestUniqueSubsttr(str); printf(“\nThe length of the longest non-repeating character substring is :%d”, len); getchar(); return 0; }

• pritybhudolia

Previous code is not pasted properly. I have used hashing.Try this

``` ```
#include<stdio.h>
#include<conio.h>
int longestUniqueSubsttr(char str[])
{
int hash[256]={0};
int start=0,max=0,i=0,j=0,end=0,begin=0;
for(i=0;i<strlen(str);i++)
{
if(hash[str[i]]==1)
{
start=end;
end=i;
if((end-start)>max)
{
max=end-start;
begin=start;
j=end;
}
}
hash[str[i]]=1;
}
printf("The longest non-repeating character substring is :");
for(start=begin;start<=j;start++) printf("%c",str[start]);
return max;
}

int main()
{
char str[] = "GEEKSFORGEEKS";
printf("The input string is :%s \n", str);
int len =  longestUniqueSubsttr(str);
printf("\nThe length of the longest non-repeating character substring is :%d", len);

getchar();
return 0;
}

``` ```
• Akash

Hi, I guess the program returns length as 0 if all the characters in the input string are unique. This is because you are entering the if statement where the max variable is updated only when you find that there is a repeating character.

Also, in current scenario I guess you have missed to check whether the repeated character that you are checking is included in length of NRCS or not. That is why its giving the output of length of longest NRCS as 6 for the input string “GEEKS FORGEEKS”.

I guess this might help. Please correct me if wrong.

``` ```
/* Paste your code here (You may delete these lines if not writing code) */
``` ```
• MVN Murthy

Take This Input – abcabcdabcdeabcdefga
Output should be – abcdefg

because you are not maintaining hash table.when encounter some duplicates you should change hash table respective values.

Following is the Modification. Correct me if i m wrong.

#include

using namespace std;

void check(char *s,int n)
{
int *count,i,begin,end,m=-100,s_w;
s_w = begin = end = 0;
count = new int [256];

for(i=0;i m)
{ m = i-begin;s_w = begin;end = i-1;}

while(count[s[i]]) {count[s[begin]]=0; begin++;}
begin = i;

}

count[s[i]]++;

}

// check whether all characters in string are non repeating
if(i-begin-1 > m)
{ m = i-begin;s_w = begin;end = i-1;}

for(i = s_w;i<=end ;i++) cout<<s[i];

cout<<endl;
cout<<"Length of the non repeating string is: "<<end-s_w+1;
cout<<endl;

}

int main (int argc, char const* argv[])
{
string s;
getline(cin,s);

check(&s[0],s.length());
return 0;
}

• Prateek Sharma

python code with o(n) time complexity based on approach similar to KMP algo….

``` ```
storingList =[]
def recursion(list1,tempArray,initial,i,len1):
if i == len1:
storingList.append(list1[initial:i])
return 0
else:
if tempArray[list1[i]][0] !=1:
tempArray[list1[i]] = [1,i]
i = i+1
recursion(list1,tempArray,initial,i,len1)
else:
storingList.append(list1[initial:i])
initial = tempArray[list1[i]][1]+1
tempArray[list1[i]][1]  =i
i = i+1
recursion(list1,tempArray,initial,i,len1)
def recursion1(list1,tempArray,initial,i,len1):
if i == len1:
storingList.append(list1[initial:i])
return 0
else:
if tempArray[ord(list1[i])][0] !=1:
tempArray[ord(list1[i])] = [1,i]
i = i+1
recursion1(list1,tempArray,initial,i,len1)
else:
storingList.append(list1[initial:i])
initial = tempArray[ord(list1[i])][1]+1
tempArray[ord(list1[i])][1]  =i
i = i+1
recursion1(list1,tempArray,initial,i,len1)

def longestSubstring(s,bool):
initial = 0
list2 =[]
list1 = list(s)
if bool == True:
for i in list1:
list2.append(int(i))
list1 = list2
len1 = len(s)
if bool == True:
maxi = max(list1)
else:
maxi = ord(max(list1))
tempArray = [[0,0] for _dummy in xrange(maxi+1)]
if bool == True:
recursion(list1,tempArray,initial,0,len1)
else:
recursion1(list1,tempArray,initial,0,len1)
maxi = 0
for i in storingList:
if len(i)>maxi:
maxi = len(i)
for i in storingList:
if len(i) == maxi:
if bool == True:
list3 =[]
for j in i:
list3.append(str(j))
print "".join(list3)
else:
print i

def main():
str = "abcdefgabc"
bool =  str.isdigit()
longestSubstring(str,bool)
if __name__ == '__main__':
main()
``` ```
• keshav

Each character need to refer its subsequent character for longest sub-string till that character. In case current character has been found already then we need to check if its most previous index lies outside the range of sub-string length of subsequent character.

``` ```
/* #include<stdio.h>
#include<conio.h>
#include<string.h>

int main()
{
char str[100];
int n,i,*ref,hash[256],max,Index;
printf("enter the string\n");
gets(str);
n=strlen(str);
ref= (int *)(malloc(n*(sizeof(int))));
for(i=0;i<n;i++)
hash[str[i]]=-1;
hash[str[n-1]]=n-1;
ref[n-1]=1;
max=1;
Index=n-1;
for(i=n-2;i>=0;i--)
{
if(hash[str[i]]==-1||hash[str[i]]>(i+ref[i+1]))
ref[i]=ref[i+1]+1;
else
ref[i]=hash[str[i]]-i;
hash[str[i]]=i;
if(ref[i]>max)
{
max=ref[i];
Index=i;
}
}
printf("\nLongest substring without repetitions is:");
for(i=Index;i<(Index+max);i++)
printf("%c",str[i]);
getch();
return 1;
}
*/
``` ```
• Code1101
``` ```
public int largestUniqueString(String s) {
Set<Character> set = new HashSet<Character>();
int[] w = new int[s.length()];
for(int i=0; i<s.length(); i++) {
if(set.contains(s.charAt(i))) set.clear();

w[i] = set.size();
}

int max=-1;
for(int i=0; i<w.length; i++) {
if(w[i] > max) {
max = w[i];
}
}
return max;
}
``` ```
• rahul.titare
``` ```
int start=0,stop=0,longestStart=0,longestStop = 0;

int[] counts = new int[65];

int lastCheckedPosition = -1;

String a = "GEEKSFORGEEKS".toUpperCase();
counts[a.charAt(0) - 65] = 1;

for(int i=1;i < a.length();i++){

if(counts[a.charAt(i)%65] == 0){

stop = i;

counts[a.charAt(i)%65] = i+1;

}else{

int pos = counts[a.charAt(i)%65];

if(lastCheckedPosition < pos){

if(stop-start > longestStop-longestStart){
longestStop = stop;
longestStart = start;
}

start = pos;
stop = i;
lastCheckedPosition = start;
}

counts[a.charAt(i)%65] = i+1;

}

}

if(stop-start > longestStop-longestStart){
longestStop = stop;
longestStart = start;
}

System.out.println("Logest substring is : "+a.substring(longestStart, longestStop+1));
``` ```

``` ```
cur_len = i - prev_index;
``` ```

the following would also work.

``` ```
cur_len--;
``` ```
• Also initialise curr_len to ‘0’

• Arun

Java implementation for the same::

public static String findSubsString(String str){

HashSet set = new HashSet();

int max_curr = 0;
int max_overAll = 0;
int tail = 0;
String longestSubstring = “”;

while(tail < str.length()){

if(!set.contains(str.charAt(tail))){
max_curr++;
}else{
int i = 0;
for(Character c : set){
i++;
if(c == str.charAt(tail)){
break;
}
}

for(int j = head ; j max_overAll){
max_overAll = max_curr;
}
}
tail++;
}
return longestSubstring;
}

• time pass

the solution ( linear time ) gives output as 1 even in case of empty strings .. i think a check should be added at the begining of the function for n .. in case n is 0 , return 0

``` ```
/* Paste your code here (You may delete these lines if not writing code) */
``` ```
• Saurabh Jain

import java.util.HashSet;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;

/**
*
* @author saurabh
*/
public class LongestSubstringWithoutRepeatingChars
{
String s;

public LongestSubstringWithoutRepeatingChars()
{
Scanner sc = new Scanner(System.in);
s = sc.nextLine();
System.out.println("\nLength of longest substring without repeating chars is : "+printLengthOfLongestNonRepeatingSubstring2());
}

private int printLengthOfLongestNonRepeatingSubstring2()
{
int start=0,len=1;
Set<Integer> subIndex = new HashSet<Integer>();
int[] v = new int[256];

for(int i=0; i<256; i++)
v[i]=-1;

for(int i=0; i<s.length() && start<s.length(); i++)
{
if(v[s.charAt(i)]<start)
{
v[s.charAt(i)]=i;
}
else
{
start=v[s.charAt(i)]+1;
v[s.charAt(i)]=i;
}

if(i-start+1>len)
{
len = i-start+1;
subIndex.clear();
}
else if(i-start+1==len)
{
}
}

System.out.print("Longest Substrings without repeating characters is : ");
Iterator<Integer> it = subIndex.iterator();
while(it.hasNext())
{
int l = it.next();
System.out.println();
for(int i=l; i<l+len; i++)
System.out.print(s.charAt(i));
}

return len;
}

public static void main(String[] args)
{
LongestSubstringWithoutRepeatingChars lswrc = new LongestSubstringWithoutRepeatingChars();
}
}

This program prints all longest substrings without repeating characters. Time Complexity O(n+d), Space Complexity O(d). Correct me, if anything is wrong.

• anubhav gupta

#include <iostream>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

void compute(char *str,int *mins , int *maxs)
{
int begin,end,count=0,maxcount=-1;
map<char,int> hash;
hash.clear();

for(begin = 0,end = 0 ;end < strlen(str); end++){

hash[str[end]]++;

if(hash[str[end]]>1){

while(hash[str[end]]>1)
{
hash[str[begin]]–;

begin ++ ;
}
}
count = end-begin+1;
if(count > maxcount)
{
maxcount = count;
*maxs = end;
*mins = begin;
}
}
}

int main()
{

char *str = "THISISASTRING";
int mins,maxs;
compute(str,&mins,&maxs);
for(int i= mins;i <= maxs ;i++)
printf("%c",str[i]);
printf("\n");
system("pause");
}

• Raghav

A simple code as below would work for the O(n) solution

``` ```
int retMaxLenSubString(char str[]){
if(str == null || str.length==0)
return 0;
int charIndex[] = new int[256];
for(int i=0;i<256;i++) {
charIndex[i] = -1;
}

int maxLenStIndex = 0;
int maxLen = 0;

for(int i=0;i<str.length;i++) {
int asciiValue = (int)str[i];
if(index[asciiValue]>maxLenStIndex) {
maxLenStIndex = index[asciiValue] + 1;
}
index[charIndex] = i;
maxLen = max(maxLen, i-maxLenStIndex;
}
}
``` ```

#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

void getLongestSubstringWithoutRepeatingChars(char* s) {
int n = strlen(s);
int lo = 0, hi = 0, t_lo = 0, t_hi = 0, max = 0, curr = 0;
int ht[256];
memset(ht, -1, 256 * sizeof(int));

for (int i = 0; i < n; ++i) {
if (ht[s[i]] != -1) {
for (; lo <= ht[s[i]]; ++lo) {
ht[s[lo]] = -1;
–curr;
}
}
ht[s[i]] = i;
++curr;
t_hi = i;
if (max < curr) {
max = curr;
lo = t_lo;
hi = t_hi;
}
}
cout << max << endl;
}

int main() {
char* s = new char[64];
strcpy(s, "geeksforgeeks");
getLongestSubstringWithoutRepeatingChars(s);
strcpy(s, "ABDEFGABEF");
getLongestSubstringWithoutRepeatingChars(s);
strcpy(s, "BBACDBV");
getLongestSubstringWithoutRepeatingChars(s);
strcpy(s, "AAA");
getLongestSubstringWithoutRepeatingChars(s);
return 0;
}

``` ```
#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

int getLongestSubstringWithUniqueChars(const char* s) {
int n = strlen(s);
bool ht[256];
memset(ht, false, 256 * sizeof(bool));
int max = -1, curr = 0;
for (int i = 0; i < n; ++i) {
if (ht[s[i]]) {
curr = 0;
memset(ht, false, 256 * sizeof(bool));
}
++curr;
ht[s[i]] = true;
if (max < curr) {
max = curr;
}
}
return max;
}

int main() {
cout << getLongestSubstringWithUniqueChars("ABDEFGABEF") << endl;
return 0;
}
``` ```
• Rushi Agrawal

Check the python code for the same. Looks quite elegant to me.

from string import ascii_lowercase

def maxss(s):
s = list(s)
maxlen = 0
maxsofar = 0
lastinstance = {}
for i in ascii_lowercase:
lastinstance[i] = -1
for i in range(len(s)):
if lastinstance[s[i]] < i – maxsofar:
lastinstance[s[i]] = i
maxsofar += 1
else:
maxsofar = i – lastinstance[s[i]]
lastinstance[s[i]] = i
if maxsofar > maxlen:
maxlen = maxsofar
return maxlen

• Rushi Agrawal

Correction in the above code: The line s = list(s) can and must be removed.

lastinstance is the dictionary to keep track of the last instance of the characters. Current implementation only works with smallcase alphabets, although can be scaled easily to larger character set.

• vikram.kuruguntla

Program to print the one of maximum sub string which has unique chars. Characters are case sensitive.

Please correct me, if anything is wrong.

``` ```
#include "stdafx.h"
#include <iostream>
using namespace std;
#define NUM_CHARS 256

int _tmain(int argc, _TCHAR* argv[])
{
char *input_string = "ABCabc";
int input_length = strlen(input_string);
char first_char_of_current_string = 0;

char visited[NUM_CHARS];
memset(visited, 0, sizeof(char) * NUM_CHARS);

int current_start_ix = 0, final_start_ix = -1, final_end_ix = -1;
int current_length=0;
int final_length=0;
for( int i = 0; i < input_length; i++)
{
if(visited[ input_string[i] ] == 0)
{
visited[ input_string[i] ] = 1;
current_length++;
}else if( current_length > final_length){

final_start_ix = current_start_ix;
final_end_ix = i - 1;
final_length = current_length;

if(first_char_of_current_string && visited[first_char_of_current_string ] == 0)
{
final_start_ix--;
final_length++;
}

current_length = 0;
memset(visited, 0, sizeof(char) * NUM_CHARS);
first_char_of_current_string = input_string[i];
current_start_ix = i + 1;
}
}

if( current_length > final_length)
{
final_start_ix = current_start_ix;
final_end_ix	= input_length;
if(first_char_of_current_string && visited[first_char_of_current_string] == 0)
{
final_start_ix--;
final_length++;
}
}

for( int i = final_start_ix; i <= final_end_ix; i++)
cout << input_string[i];
cout << endl;

return 0;
}

``` ```
• program is wronge

• randy

char str[] = “ABCDECQWERTYU”;

The program does not work.

``` ```
/* Paste your code here (You may delete these lines if not writing code) */
``` ```
• GeeksforGeeks

@randy: The program given in the post return 8 for “ABCDECQWERTYU” which seems to be correct. CQWERTYU is the longest string without repeating characters.

• randy

Yes It is correct, sorry for my mistake.

``` ```
/* Paste your code here (You may delete these lines if not writing code) */
``` ```
• itengineer
``` ```
package com.sun.java.longestsubstring;

public class LongestSubstring
{
private int visitedStartIndex = 0;
private int previousIndex = 0;

public static void main(String[] args)
{
LongestSubstring lsObject = new LongestSubstring();
System.out.println("length = " + lsObject.findNRCSLength("uniquesubstring"));
}

/**
* @return  Non Repeating Character Substring length
*/

public int findNRCSLength(String string)
{
int maxLength = -1;
int currentLength = 1;
char stringChars[] = (string.toLowerCase()).toCharArray();

for(int currentIndex = 1; currentIndex < stringChars.length; currentIndex++)
{

if(!isCharVisited(currentIndex, stringChars))
{
currentLength++;
}
else
{
maxLength = currentLength > maxLength ? currentLength : maxLength;
currentLength = 1;
visitedStartIndex = currentIndex;
}

previousIndex = currentIndex;
}

maxLength = currentLength > maxLength ? currentLength : maxLength;

return maxLength;
}

private boolean isCharVisited(int index, char[] str)
{
for(int i = visitedStartIndex; i <= previousIndex; i++)
{
if(str[index] == str[i])
{
return true;
}
}

return false;
}
}
``` ```

output
length = 8

• itengineer

Hey Geeks,

Forgot to mention that the code above uses JAVA language.

• vkjk89

Here is one more code.
Venki/Kartik,
Plz suggest if anything wrong.

``` ```
#include<stdio.h>
#include<conio.h>
#include<string.h>
int longest(char * str ,int *pos)
{
int len;
int i,cur,max,*vis;
vis=(int*)malloc(sizeof(int)*256);
for(i=0;i<256;i++)
vis[i]=-1;
cur=max=0;
len=strlen(str);
for(i=0;i<len;i++)
{
if(vis[str[i]]==-1||i-cur>vis[str[i]])
{
vis[str[i]]=i;
cur++;
}
else if(cur>max)
{
*pos=i;
max=cur;
cur=1;
vis[str[i]]=i;
}
else cur=1;
}
free(vis);
*pos=(*pos)-max;
return max;

}

int main()
{
char *str="geeksforgeeks";
char *sub;
int lo;
int pos;
clrscr();
lo=longest(str,&pos);
strcpy(sub,str+pos);
sub[lo]='\0';
printf("substring=%s",sub);
getch();
return 0;
}

``` ```
• AKKICOOL

Can you please give a case for

“when we are changing the NRCS, we should also check whether length of the previous NRCS was greater than max_len or not” in else part

``` ```
/* Paste your code here (You may delete these lines if not writing code) */
``` ```
• Arpit Gupta

In this article complexity of brute force algorithm is written as exponential but it should be O(n^3) because there will be n*(n+1)/2 substrings and considering each of atmost length n the complexity should be O(n^3).Please let me know how can it be exponential.

``` ```
/* Paste your code here (You may delete these lines if not writing code) */
``` ```
• GeeksforGeeks

@Arpit Gupta: Thanks for pointing this out. We have updated the post with time complexity as O(n^3).

• camster

Here is a recursive function that finds and prints the length of the longest substring in O(N) time complexity, O(N) space.

``` ```
void lcs(char arr5[], int n, int curr,
int&  maxlength,std::string& sofar){
if (n == 0){
return;
}
if (arr5[0] == arr5[1]){
if (curr >= maxlength){
if (n < sofar.length()){
maxlength = sofar.length();
return;
}
sofar.clear();
}
maxlength = MAX(maxlength,curr);
lcs(arr5 + 1, n - 1, curr + 1,
maxlength,sofar);
}
else if (arr5[0] != arr5[1]){
sofar.push_back(arr5[0]);
maxlength = sofar.length();
lcs(arr5 + 1, n - 1,
curr + 1, maxlength,sofar);
}
}

// testing

char cameron[] =  {'g','e','e','k','s','f','o','r','g','e','e','k','s'};
int maxlength(0);
std::string resultstring;

lcs(cameron, sizeof(cameron), 0, maxlength,resultstring);

printf("maxlength = %d resultstring = %s\n",
maxlength, resultstring.c_str());

/* Paste your code here (You may delete these lines if not writing code) */
``` ```
• PsychoCoder
``` ```
#include<stdio.h>
#include<string.h>

int main() {
char arr[26] , str[40] ;
int i , len, index ;
int start, maxlen = 1 , end = 0 ;
printf ( "\nEnter the string :\t " ) ;
scanf( "%s", str ) ;
len = strlen (str) ;
start = 0 ;

for ( i = 0 ; i < 26 ; i ++ )
arr[i] = -1 ;
arr[str[0]-'a'] = 0 ;

for ( i = 1 ; i < len ; i ++ ) {
index = str[i] - 'a' ;
if ( arr[index] >= start ) {
if ( (i - start) > maxlen ) {
maxlen = i-start ;
end = i - 1;
}
start = arr[index] + 1 ;
}
arr[index] = i ;
}
if ( (i-start) > maxlen ) {
maxlen = i-start ;
end = i - 1 ;
}
printf ( "\nMax length is : \t%d", maxlen ) ;
printf ( "\nIndex (start : %d - end : %d)", end-maxlen+1, end) ;
return 0;
}
``` ```
• suresh
``` ```
/* Paste your code here (You may delete these lines if not writing code) */
``` ```

for “geeksforgeeks” it print 7

• You can reduce the space further by storing indexes instead of the array itself. Below is a solution in Java that also prints the substring.

public class LONGESTSTRING {
public static void main(String[] args) {
String str = "GEEKSFORGEEKS";
System.out.println("The input string is " + str);
int len = longestUniqueSubsttr(str);
System.out
.println("The length of the longest non-repeating character substring is "
+ len);
}

private static int longestUniqueSubsttr(String str) {
if (str.length() == 1)
return 1;
short back_ptr = 0, front_ptr = 1, max_len = -1, cur_len = 1;
short max_back_ptr = -1, max_front_ptr = -1;
for (short i = 1; i < str.length(); i++) {
if (!characterExits(str, front_ptr, back_ptr, i)) {
cur_len++;
front_ptr++;
} else {
if (max_len < cur_len) {
max_len = cur_len;
max_back_ptr = back_ptr;
max_front_ptr = front_ptr;
}
cur_len = 1;
back_ptr = i;
front_ptr = (short) (i + 1);
}
}

if (max_len == -1) {
max_len = cur_len;
max_back_ptr = back_ptr;
max_front_ptr = front_ptr;
}
printLSNC(str, max_back_ptr, max_front_ptr);
return max_len;
}

private static void printLSNC(String str, short back_ptr, short front_ptr) {
if (str.length() <= back_ptr || str.length() < front_ptr)
return;
for (int i = back_ptr; i < front_ptr; i++) {
System.out.print(str.charAt(i));
}
System.out.println();
}

private static boolean characterExits(String str, short front_ptr,
short back_ptr, short cur) {
if (str.length() <= back_ptr || str.length() < front_ptr)
return false;
if (cur < 0 || cur > str.length())
return false;
for (int i = back_ptr; i < front_ptr; i++) {
if (str.charAt(i) == str.charAt(cur))
return true;
}
return false;
}
}

/**
* Output
The input string is GEEKSFORGEEKS
EKSFORG
The length of the longest non-repeating character substring is 7
*/

• Rahul
``` ```
int uniquesubstrlength (const char *str)
{
int curlen = 1, maxlen = 0;
int n = strlen (str);
int *visited = (int *) calloc (256, sizeof (int));
int tag = 1;
visited [str[0]] = tag;

for (int i = 0; i < n; i++)
{
if (visited[str[i]] == tag)
{
if (curlen > maxlen)
{
maxlen = curlen;
}
curlen = 1;
visited[str[i]] = ++tag;
}
else
{
visited[str[i]] = tag;
curlen++;
}
}
if (curlen > maxlen)
maxlen = curlen;
free (visited);
return maxlen;
}

``` ```
• camster
``` ```
/* Paste your code here (You may delete these lines if not writing code) */
``` ```
• camster

A hashtable , STL map givea the same result. Also, I was wondering if the Knuth Pratt Moore string matching code , which has a worst cas running time of O(N) could be used to help solve this problem. Thank you for your excellent algorithm.

``` ```
/* Paste your code here (You may delete these lines if not writing code) */
int longestUniqueSubsttr(char *str) {
int n = strlen(str);
int cur_len = 1;  // To store the lenght
int max_len = 1;  // To store the result
int prev_index;  // To store the previous inde
int i;
std::map<char,int> visited;

visited[str[0]] = 1;
for (i = 1; i < n; i++)   {
prev_index =  visited[str[i]];
if (prev_index == 0 ||
i - cur_len > prev_index)
cur_len++;
else{
if (cur_len > max_len)
max_len = cur_len;
cur_len = i - prev_index;
}
visited[str[i]] = i;
}

if (cur_len > max_len)
max_len = cur_len;
return max_len;
}

``` ```
• camster

It is possible to find and print the longest substring without repeating characters in 0(n + d) running time. Thank you,

int PrintLongestUniqueSubsttr(char *str) {
int n = strlen(str);
int cur_len = 1;
int max_len = 1;
int prev_index;
int i;
int lastn(0);
std::map visited;

visited[str[0]] = 1;
for (i = 1; i prev_index) {
cur_len++;
if (prev_index == 0){
lastn = i;
}
}
else {
if (cur_len > max_len){

max_len = cur_len;
}
cur_len = i – prev_index;
}
visited[str[i]] = i;
}
if (cur_len > max_len)
max_len = cur_len;
char* answer = new char[max_len + 1];
int ii(0);
for (int m = lastn – max_len +1;

• mystry

Point out if something is wrong.
// works for lower case letters but can easily be tweaked for upper case also.

``` ```
// Longest Common Substring without Repeatition
#include<stdio.h>
int main(){
//	char Input[]="bbbb";
//	char Input[]="abdefgabef";
char Input[]="geeksforgeeks";
int Array[26];
int start_index=0,curr_len=0,max_len=0;
int i;
for(i=0;i<26;i++)
Array[i]=-1;
for(i=0;i<sizeof(Input);i++){
if(Array[(int)(Input[i])-97]==-1){
Array[(int)(Input[i])-97]=i;
curr_len++;
}
else{
if(Array[(int)(Input[i])-97]==i-curr_len){
Array[(int)(Input[i])-97]=i;
//				start_index++;
}
else{
if(curr_len>max_len){
max_len=curr_len;
start_index=i-curr_len;
curr_len=i-Array[(int)(Input[i])-97]-1;
}
}
}
}
printf("\nMax_len\t%d\n",max_len);
}
``` ```

This is O(n) time
and O(1) space // int array of 26.

• chakri

The above program does not work for the below input of characters.
char str[] = “BBACDBV”;

• kartik

@Chakri: The program works perfectly fine for your string, it returns 5 as “ACDBV” is the maximum length substring with unique characters.