如何在字母表数组中定位字符以求解最长有序连续子串问题
解决字母连续子串长度问题及字符定位错误
核心问题分析
你用alphabet[currentChar]得到undefined的原因是:数组只能通过数字索引访问,而你用字符(比如'a')作为索引,数组中不存在这个键,所以返回undefined。
正确的字符定位方法
方法1:使用数组indexOf方法
直接调用数组的indexOf方法获取字符在字母表中的位置:
const position = alphabet.indexOf(currentChar); // 比如currentChar是'g',position会返回6
缺点:每次调用都要遍历数组,性能略差,但对于小写字母来说影响可以忽略。
方法2:利用ASCII码计算(最优)
通过字符的ASCII码差值直接计算位置,无需额外数组或对象,效率最高:
const position = currentChar.charCodeAt(0) - 'a'.charCodeAt(0); // 'a'的ASCII码是97,'g'是103,103-97=6,对应正确位置
方法3:构建哈希表(对象)
如果想用哈希表快速查找,可以把字母表转为字符-索引映射的对象:
const alphabet = ['a', 'b', 'c', ..., 'z']; // 用forEach构建映射 const charMap = {}; alphabet.forEach((char, idx) => { charMap[char] = idx; }); // 或者用reduce更简洁 const charMap = alphabet.reduce((map, char, idx) => { map[char] = idx; return map; }, {}); // 之后直接通过字符获取位置 const position = charMap[currentChar]; // 'g'会返回6
完善后的完整代码
结合你的双指针思路,修复字符定位问题并完成最长连续子串的逻辑:
let str2 = 'abcdggrisxzy'; const alphaString = function(s) { if (s.length <= 1) return s.length; let maxLength = 1; let currentLength = 1; for (let i = 1; i < s.length; i++) { // 用ASCII码计算当前字符和前一个字符的位置差 const prevPos = s[i-1].charCodeAt(0) - 'a'.charCodeAt(0); const currPos = s[i].charCodeAt(0) - 'a'.charCodeAt(0); // 判断是否连续:当前位置 = 前一个位置 +1 if (currPos === prevPos + 1) { currentLength++; maxLength = Math.max(maxLength, currentLength); } else { // 不连续则重置当前长度 currentLength = 1; } } return maxLength; }; console.log(alphaString(str2)); // 输出4(对应'abcd') console.log(alphaString('abcqrstz')); // 输出4 console.log(alphaString('abcbyyxz')); // 输出3
代码说明
- 去掉了不必要的字符串拆分,直接通过字符串索引访问字符
- 用ASCII码计算位置差,避免了数组或哈希表的额外开销
- 单循环遍历,时间复杂度O(n),空间复杂度O(1),效率最优
- 维护
currentLength记录当前连续子串长度,maxLength记录最大值,遇到不连续字符时重置currentLength
内容的提问来源于stack exchange,提问作者lss555
相关产品推荐
相关产品推荐

