The question is on leetcode, No 3:
https://leetcode.com/problems/longest-substring-without-repeating-characters/submissions/
Here is my code:
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
console.log('input', s);
var max_length = s.length;
var results = [];
var isDupCheck = function(arr){
var s = [];
var hasDup = false;
arr.forEach(function(el){
if (!s.includes(el)) {
s.push(el);
} else {
hasDup = true;
}
})
return hasDup;
}
for (var j = 0; j<max_length; j++)
for (var i = 1; i<max_length; i++) {
var substr = s.substr(j, i);
var isDup = isDupCheck(substr.split(''));
if (!isDup) {
results.push(substr);
}
}
var length = 0;
var picked;
console.log("results:", results);
results.forEach(function(el){
if (el.length > length) {
length = el.length;
picked = el;
}
});
var picked_length = picked.split('').length;
console.log(picked_length); // expected output
return 5; // If I comment this line, there will be an ERROR.
return picked_length;
};
The console.log(picked_length) outputs exactly the expected solve. But if I return the picked_length, then submit, there will be an error:
Line 42 in solution.js
var picked_length = picked.split('').length;
^
TypeError: Cannot read properties of undefined (reading 'split')
Line 42: Char 30 in solution.js (lengthOfLongestSubstring)
Line 57: Char 19 in solution.js (Object.<anonymous>)
Line 16: Char 8 in runner.js (Object.runner)
Line 48: Char 26 in solution.js (Object.<anonymous>)
at Module._compile (node:internal/modules/cjs/loader:1101:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47
>Solution :
My guess is that they’re giving you an empty string, based on their constraints –
0 <= s.length <= 5 * 104
Looking at your code here –
var picked;
console.log("results:", results);
results.forEach(function(el) {
if (el.length > length) {
length = el.length;
picked = el;
}
});
If there are no results, then you’re not assigning anything to picked. If you initialize it to an empty string, the problem should go away.
Edit
For what it’s worth, I couldn’t help but try the problem myself. It’s deceiptively difficult to solve without violating their constraints for time/memory, but this was the best solution I could come up with… it works well because a javascript Set guarantees iteration order, but the lookup time for an element should be faster than using an array:
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
if (!s?.length) return 0;
let longest = 0;
let seenChars = new Set();
for (const char of s) {
if (seenChars.has(char)) {
longest = Math.max(longest, seenChars.size);
for (const seenChar of seenChars) {
seenChars.delete(seenChar);
if (seenChar === char) break;
}
}
seenChars.add(char);
}
return Math.max(longest, seenChars.size);
};