Reputation: 2253
So the problem I'm trying to solve this problem given a string, find the length of the longest substring without repeating characters. I'm aware of the HashMap based solution, but that fails in case of overlapping substrings.Here's my code.
public static int lengthOfLongestSubstring(String s) {
Deque<Character> primary = new ArrayDeque<>();
Deque<Character> secondary = new ArrayDeque<>();
for (int i = 0; i < s.length() ; i++) {
char c = s.charAt(i);
if(primary.contains(c)){
while(primary.peek() != c){
secondary.offerLast(primary.poll());
}
secondary.offerFirst(c);
primary = secondary;
secondary.clear();
}else{
primary.offerFirst(c);
}
}
return primary.size();
}
This fails at the line where I do primary = secondary
otherwise I think I'm doing it right logically.
To test the correctness I'm using the string dvdf
Can someone help me understand why this is not working.
Upvotes: 2
Views: 1288
Reputation: 29
/*C++ program to print the largest substring in a string without repetation of character.
eg. given string :- abcabbabcd
largest substring possible without repetition of character is abcd.*/
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str,str1;
int max =0;
string finalstr;
vector<string> str2;
cin>>str;
int len = str.length();
for(int i=0;i<len;i++)
{
if(str1.find(str[i]) != std::string::npos)
{
str2.push_back(str1);
char p = str[i];
str1 = "";
i--;
while(p!=str[i])
i--;
}
else
str1.append(str,i,1);
}
str2.push_back(str1);
for(int i=0;i<str2.size();i++)
{
if(max<str2[i].length()){
max = str2[i].length();
finalstr = str2[i];
}
}
cout<<finalstr<<endl;
cout<<finalstr.length()<<endl;
}
Upvotes: 0
Reputation: 2456
I am wondering this:
primary = secondary;
secondary.clear();
It's assignment by reference. You set primary
and secondary
to point to the same data and clear it. Is that your intention?
What about this:
public static int lengthOfLongestSubstring(String s) {
Deque<Character> primary = new ArrayDeque<>();
Deque<Character> secondary = new ArrayDeque<>();
Deque<Character> longest = new ArrayDeque<>();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (primary.contains(c)) {
// Store longest
if (primary.size() > longest.size()) {
longest = new ArrayDeque<>(primary);
}
while (primary.peek() != c) {
secondary.offerLast(primary.poll());
}
secondary.offerFirst(c);
primary = secondary;
secondary = new ArrayDeque<>(); // Altered
} else {
primary.offerFirst(c);
}
}
// Also check at end of line.
if (primary.size() > longest.size()) {
longest = primary;
}
return longest.size();
}
OUTPUT
dvdf
=> 3dvdfvadv
=> 4EDIT
Your logic is right. I just altered one line.
EDIT
Keep track of the longest.
Upvotes: 1
Reputation: 1
You can try this:
public class LongestSubstring {
public static void main(String [] args){
System.out.println(longestSub("abcdefgghij"));
//prints 7 abcdefg g is repeated character
}
public static int longestSub(String s) {
if(s==null)
return 0;
boolean[] flag = new boolean[256];
int result = 0;
int start = 0;
char[] arr = s.toCharArray();
for (int i = 0; i < arr.length; i++) {
char current = arr[i];
if (flag[current]) {
result = Math.max(result, i - start);
// the loop update the new start point and reset flag array
for (int k = start; k < i; k++) {
if (arr[k] == current) {
start = k + 1;
break;
}
flag[arr[k]] = false;
}
} else {
flag[current] = true;
}
}
result = Math.max(arr.length - start, result);
return result;
}
}
Upvotes: 0
Reputation: 2525
May not be exact answer you were looking. Try to avoid using ArrayDeque in a multi threaded env as it is not thread safe.
Go through this link::
Find longest substring without repeating characters
this returns a string. you can use .length() method and find the length as you require.
Hope it helps.
Upvotes: 1