3

I was asked this question in a recent interview. I need to find the longest substring without repeating characters.

Given "abcabcbb", the answer is "abc", which the length is 3.

Given "bbbbb", the answer is "b", with the length of 1.

Given "pwwkew", the answer is "wke", with the length of 3

This is what I came up with, I think it works correctly, but the interviewer was not impressed and said that my solution may not work for all cases.

    var str = "pwwkew";
    var longSubstring = function(str) {
      var obj = {}; //map object
      var count = 0;
      var c = []; //count array to keep the count so far
      for (var i = 0; i < str.length; ++i) {
        //check if the letter is already in the map
        if (str[i] in obj && obj[str[i]] !== i) {
          c.push(count); //we encountered repeat character, so save the count
          obj = {};
          obj[str[i]] = i;
          count = 1;
          continue;
        } else {
          obj[str[i]] = i;
          ++count;
        }
      }
      return Math.max.apply(null, c);
    }
    console.log(longSubstring(str)); //prints 3

Can anyone tell me what's the problem with my solution? I think it is one of the best :) and also solves in O(n) time.

Wild Widow
  • 2,359
  • 3
  • 22
  • 34
  • What's "aaaabbbbaaaabbbbaaaabbbb" meant to return? – wot Jun 09 '16 at 09:23
  • 1
    @e4en it should return 2. any of the ab, ba...my code works for this too – Wild Widow Jun 09 '16 at 09:25
  • 1
    @WildWidow .what would be the output if input is 'abc'.It returns -Infinity – Sunil Hari Jun 09 '16 at 09:28
  • @Shadow it should be 3. my code is not working for this case and I don't know why? – Wild Widow Jun 09 '16 at 09:30
  • @WildWidow It could be an issue then.Will see if i can find a more better approach.Meanwhile try to find why its not working :) – Sunil Hari Jun 09 '16 at 09:33
  • 1
    @WildWidow:This post appears to have a better approach.Please see this http://stackoverflow.com/questions/9734474/find-longest-substring-without-repeating-characters – Sunil Hari Jun 09 '16 at 09:50
  • 1
    Your solution is probably working fine yet i don't think it is O(n) time solution. You do n times `str[i] in obj` operation. – Redu Jun 09 '16 at 10:02

1 Answers1

1

I guess the problem with your code is, it gets haywire when there is no repeating letters in the whole sentence to start with. As mentioned in one of the comments "abc" won't produce a correct result. My approach would be slightly different than yours as follows;

var str = "pwwkew",
   data = Array.prototype.reduce.call(str, (p,c) => (p.test.includes(c) ? p.test = [c]
                                                                        : p.test.length >= p.last.length ? p.test = p.last = p.test.concat(c)
                                                                                                         : p.test.push(c)
                                                                        , p), {last:[], test:[]}),
result = data.last.length;
console.log(data);
console.log(result);

In this reduce code we initially start with an object like {last:[], test:[]} and go over the characters one by one. If the received character is in our objects's test array we immediately reset the test array to include only the letter we tested (the p.test = [c] line). However If the received character is not in our test array then we do either one of the two thing as follows. If our test array's length is equal or longer than the last array's length then we add the current character to test array and make last array = test array. (p.test.length >= p.last.length ? p.test = p.last = p.test.concat(c) line). But if our test array's length is shorter than the last array's length we just add the current character to test array and continue likewise all the way to the end of the string one by one over single characters.

Redu
  • 25,060
  • 6
  • 56
  • 76