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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 13:23:14