JS字符串压缩:求双指针/递归法精简高效实现方案
我已实现一个字符串压缩程序,当输入
chars = ["a","a","b","b","c","c","c"]时,输出为包含6个字符的数组["a","2","b","2","c","3"]。我采用数组法编写的代码冗长且复杂,请问是否存在基于双指针或递归的实现方案,能提供精简且高效的代码?以下是我的实现代码:
var compress = function(chars) { if (!chars.length) { return 0; } let j = 0; let cur = chars[0]; let counter = 0; for (let i = 0; i <= chars.length; i++) { if (chars[i] === cur) { counter++; } else { // Otherwise, add the current character and count to the compressed array chars[j] = cur; if (counter > 1) { const s = counter.toString(); for (let k = 0; k < s.length; k++) { chars[++j] = s[k]; } } j++; cur = chars[i]; counter = 1; } } return j }; console.log(compress ('aaaabbc'))//a4b2c
双指针优化方案
你的原代码其实已经用到了双指针思路(i作为快指针遍历数组,j作为慢指针记录压缩后数组的位置),可以进一步精简逻辑,让代码更清晰:
var compress = function(chars) { let j = 0; for (let i = 0; i < chars.length;) { const char = chars[i]; let count = 0; // 统计当前字符的连续出现次数 while (i < chars.length && chars[i] === char) { i++; count++; } // 写入当前字符 chars[j++] = char; // 次数大于1时写入数字 if (count > 1) { for (const c of count.toString()) { chars[j++] = c; } } } return j; };
这个版本用嵌套while循环替代原有的单循环边界判断,把字符统计和写入逻辑拆分得更直观,去掉了冗余的变量初始化步骤,同时保持原地修改数组的特性,时间复杂度仍为O(n),空间复杂度O(1)。
递归实现方案
递归方案通过每次处理一段连续相同的字符,再递归处理剩余数组片段来实现压缩,代码风格更简洁,但处理超长数组时可能存在栈溢出风险,且无法原地修改原数组(返回新的压缩数组):
var compress = function(chars) { // 递归终止条件:数组为空 if (!chars.length) return []; const char = chars[0]; let count = 1; // 统计当前字符的连续次数 while (count < chars.length && chars[count] === char) { count++; } // 生成当前字符的压缩片段 const segment = [char]; if (count > 1) { segment.push(...count.toString().split('')); } // 递归处理剩余数组并合并结果 return segment.concat(compress(chars.slice(count))); };
如果需要和原函数保持“修改原数组并返回长度”的行为,递归方案会很难维护指针位置,因此双指针方案更适合这类原地操作的场景。
内容的提问来源于stack exchange,提问作者Sougata Mukherjee
相关产品推荐
相关产品推荐

