我在最近的一次采访中被问到了这个问题。我需要找到最长的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)
时间内解决。
答案 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
数组,并继续一直一直到字符串的结尾单个字符。