-5

I have a following problem here: I need to find out the length of the longest substring of unique characters.

like, I have a string thequickbrownfoxjumpsoveralazydog and I expect to get 14 (the length of thequickbrownf)

I found many topics over here related to the subject but I don't seem to be able to translate those solutions (where available) into Javascript.

Would you, guys, help me out with that? Thanks a million in advance!

  • 3
    ok, but did you get the concept of how it's done? – nice_dev Jun 12 '19 at 14:51
  • @vivek_23 : not really, I guess, that's where I have failed exactly – user11637163 Jun 12 '19 at 14:51
  • No problem, you could go through this post if you haven't before and come back with doubts(as a new question), because your current question is too broad. https://stackoverflow.com/questions/55898558/finding-longest-substring-no-duplicates-help-optimizing-code-ruby – nice_dev Jun 12 '19 at 14:54
  • This should provide you with solutions as well to better grasp. https://leetcode.com/problems/longest-substring-without-repeating-characters/discuss/?currentPage=1&orderBy=most_relevant&query=javascript – nice_dev Jun 12 '19 at 14:57
  • @user11637163 Then you should rather ask about the particular things that you did not understand in those, instead of asking for js code – Bergi Jun 12 '19 at 14:57
  • 1
    Can you add the code that you've made in your attempts? – Teun Jun 12 '19 at 14:59

3 Answers3

1

One option is to use a Set that you reset when you find a duplicate character, which runs in O(N) time:

const str = 'thequickbrownfoxjumpsoveralazydog';
let set = new Set();
let bestRecordSoFar = 0;
let currRecord = 0;
[...str].forEach((char) => {
  if (set.has(char)) {
    bestRecordSoFar = Math.max(bestRecordSoFar, currRecord);
    set = new Set();
    currRecord = 0;
  }
  set.add(char);
  currRecord++;
});

const best = Math.max(bestRecordSoFar, currRecord);
console.log(best);
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • This doesn't work in general. It gives an answer of 3 instead of 5 for `'zabzcd'` and 9 instead of 15 for `'zabzcdthequickbrownfox'` – Paul Jul 03 '19 at 17:26
1

Considering (based on your comment) you didn't really get the algorithms you have managed to find, I have supplied my code with step-by-step explanations.

The main concept is to run through the string, shifting one character to the right each time you find the duplicate and comparing the length of those unique-character substrings to find the longest one:

//input string
const src = 'thequickbrownfoxjumpsoveralazydog';
//iterate through characters
const longestUniqueSub = str => [...str].reduce((res, char, idx, self) => {
  //find first occurence of the 'char'
  const charPos = self.indexOf(char, res.anchor);
  //if didn't occur before and more chars to check, move on
  if(charPos == idx && idx < self.length - 1) return res;
  //assign res.len and shift anchor otherwise
  return {
    len: Math.max(res.len, (charPos < idx ? idx - 1 : idx) - res.anchor + 1),
    anchor: charPos < idx ? charPos + 1 : res.anchor
  };
}, {anchor: 0, len: 0}).len
//output the result  
console.log(longestUniqueSub(src));
.as-console-wrapper {min-height: 100%}
Yevhen Horbunkov
  • 14,965
  • 3
  • 20
  • 42
1

The existing answers don't work correctly, since they only search for longest unique substrings starting at specific positions (the start of the string and immediately after some duplicate characters). They happen to give the correct answer for 'thequickbrownfoxjumpsoveralazydog', since the longest unique substring is at the start of the string. They don't work for a string like 'zabzcd', where the longest string starts at the second position and has length 5.

This will work for all cases:

const tests = [
  'thequickbrownfoxjumpsoveralazydog', // 14
  'zabzcd', // 5
  'zabzcdthequickbrownfox', // 15
];

console.log( tests.map( get_max_unique_substring_length ) );

function get_max_unique_substring_length ( str ) {
  let unique_str = '';
  let max_length = 0;

  for ( let i = 0; i < str.length; i++ ) {
    const char = str[i];
    const char_pos = unique_str.indexOf( char );
    if ( char_pos >= 0 )
      unique_str = unique_str.substr( char_pos + 1 );

    unique_str += char;
    max_length = Math.max( unique_str.length, max_length );
  }

  return max_length;
}
Paul
  • 139,544
  • 27
  • 275
  • 264