没有重复字符的最长子字符串转角个案

时间:2016-06-09 09:18:39

标签: javascript arrays string time-complexity asymptotic-complexity

我在最近的一次采访中被问到了这个问题。我需要找到最长的substring而不重复字符。

鉴于“abcabcbb”,答案为“abc”,长度为3。

鉴于“bbbbb”,答案为“b”,长度为1。

鉴于“pwwkew”,答案为“wke”,长度为3

这就是我想出来的,我认为它运作正常,但面试官并没有留下深刻印象,并说我的解决方案可能不适用于所有情况。

    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

有谁能告诉我我的解决方案有什么问题?我认为它是最好的之一:)并且还在O(n)时间内解决。

1 个答案:

答案 0 :(得分:1)

我猜你的代码存在的问题是,当整个句子中没有重复的字母时,它会变得混乱。正如其中一条评论中所提到的,“abc”不会产生正确的结果。我的方法与你的方法略有不同,如下所示;

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);

在这个简化代码中,我们最初从像{last:[], test:[]}这样的对象开始,逐个遍历字符。如果收到的字符在我们对象的test数组中,我们会立即重置test数组,使其仅包含我们测试的字母(p.test = [c]行)。但是,如果收到的字符不在我们的test数组中,那么我们可以执行以下两种操作之一。如果我们的test数组的长度等于或长于last数组的长度,那么我们将当前字符添加到test数组并使last数组= test数组。 (p.test.length >= p.last.length ? p.test = p.last = p.test.concat(c)行)。但是如果我们的test数组的长度比last数组的长度短,我们只需将当前字符添加到test数组,并继续一直一直到字符串的结尾单个字符。