LeetCode 算法:字符串压缩

256 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 6 天,点击查看活动详情

字符串压缩

原题地址

字符串压缩。利用字符重复出现的次数,编写一种方法,实现基本的字符串压缩功能。比如,字符串 aabcccccaaa 会变为 a2b1c5a3。若“压缩”后的字符串没有变短,则返回原先的字符串。你可以假设字符串中只包含大小写英文字母(a至z)。

示例1:

 输入:"aabcccccaaa"
 输出:"a2b1c5a3"

示例2:

 输入:"abbccd"
 输出:"abbccd"
 解释:"abbccd"压缩后为"a1b2c2d1",比原字符串长度更长。

提示:

  • 字符串长度在[0, 50000]范围内。

思路分析

方法一

  1. 拿到题目的一瞬间想到的方法就是使用 map 来存储每个字符出现的次数,实现之后发现需要有顺序的,因此该方法行不通;
  2. 定义一个变量 count 来存储字符串中字符出现的次数;
  3. 遍历字符串,若后一个字符跟当前字符相同,则 count 值加一,若不相同,则把字符和次数都追加在结果字符串中,并且将 count 值重置为 1
  4. 最后比较结果字符串和原始字符串的长度,取短的那个返回即可。

方法二

  1. 遍历数组,使用字符最后一次出现的下标和第一次出现的下标的差值作为字符串中字符出现的次数;
  2. 若相邻两个字符串不同,则把对应的字符以及出现的次数追加到结果字符串 res 中;
  3. 比较结果字符串和原始字符串的长度,取短的那个返回即可。

AC 代码

方法一

/**
 * @param {string} S
 * @return {string}
 */
var compressString = function(S) {
    let res = ''
    let count = 1
    for(let i = 0; i < S.length; i++) {
        if(S[i + 1] === S[i]) {
            count += 1
        } else {
            res += `${S[i]}${count}`
            count = 1
        }
    }
    return res.length >= S.length ? S : res
};

结果:

  • 执行结果: 通过
  • 执行用时:72 ms, 在所有 JavaScript 提交中击败了39.47%的用户
  • 内存消耗:43.6 MB, 在所有 JavaScript 提交中击败了33.34%的用户
  • 通过测试用例:32 / 32

方法二

/**
 * @param {string} S
 * @return {string}
 */
var compressString = function(S) {
    const len = S.length
    let j = i = 0
    let res = ''
    while(j < len){
        if(S[j] != S[j+1]){
            res += S[j] + (j - i + 1)
            i = j + 1
        }
        j++
    }
    return res.length >= len ? S : res
};

结果:

  • 执行结果: 通过
  • 执行用时:68 ms, 在所有 JavaScript 提交中击败了62.25%的用户
  • 内存消耗:43.1 MB, 在所有 JavaScript 提交中击败了75.16%的用户
  • 通过测试用例:32 / 32

END