You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LeetCode第3题lengthOfLongestSubstring控制台正常但提交报错求助

解决LeetCode最长无重复子串问题时的TypeError错误

问题背景

这是LeetCode第3题(最长无重复字符的子串)的代码问题:我写的代码里,console.log(picked_length)输出完全符合预期,但注释掉return 5;改成返回picked_length时,提交就报错。

我的代码

/**
 * @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; // 注释这行就会报错
  return picked_length;
};

报错信息

Line 42 in solution.js
  var picked_length = picked.split('').length;
                             ^
    TypeError: 无法读取undefined的属性'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

问题原因与修复

核心错误原因

  1. 边界情况未处理:当输入字符串为空(s = "")时,results数组是空的,results.forEach不会执行,picked保持初始的undefined状态,调用picked.split('')自然会触发TypeError。
  2. 循环范围错误:原代码内层循环i < max_length,导致无法取到长度等于原字符串的子串(比如整个字符串无重复时,不会被加入results)。
  3. 性能冗余:存储所有符合条件的子串完全没必要,只会浪费内存,直接跟踪最大长度即可。

修正后的代码

/**
 * @param {string} s
 * @return {number}
 */
var lengthOfLongestSubstring = function(s) {
    const maxLength = s.length;
    // 空字符串直接返回0
    if (maxLength === 0) return 0;
    
    let maxResult = 1; // 非空字符串最小长度为1
    
    // 用Set优化重复检查,性能从O(n)提升到O(1)
    const hasDuplicate = (arr) => {
        const seen = new Set();
        for (const char of arr) {
            if (seen.has(char)) return true;
            seen.add(char);
        }
        return false;
    };

    for (let j = 0; j < maxLength; j++) {
        // 内层循环只需要遍历到maxLength - j,避免越界
        for (let i = 1; i <= maxLength - j; i++) {
            const substr = s.substr(j, i);
            if (!hasDuplicate(substr.split(''))) {
                maxResult = Math.max(maxResult, i);
            } else {
                // 一旦发现重复,更长的子串必然包含该重复字符,直接跳出内层循环
                break;
            }
        }
    }
    return maxResult;
};

关键优化点

  • 提前处理空字符串的边界情况,避免后续报错
  • 用Set替代数组includes检查重复,大幅提升性能
  • 不再存储所有子串,只跟踪最大长度,节省内存
  • 内层循环发现重复时直接break,减少不必要的遍历
  • 修正循环范围,确保能覆盖所有可能的子串长度

内容的提问来源于stack exchange,提问作者AGamePlayer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 13:06:17