LeetCode——443.压缩字符串

120 阅读3分钟

压缩字符串

1.题目链接:

443. 压缩字符串

2.原题描述:

给你一个字符数组 chars ,请使用下述算法压缩:

从一个空字符串 s 开始。对于 chars 中的每组 连续重复字符 :

如果这一组长度为 1 ,则将字符追加到 s 中。 否则,需要向 s 追加字符,后跟这一组的长度。 压缩后得到的字符串 s 不应该直接返回 ,需要转储到字符数组 chars 中。需要注意的是,如果组长度为 10 或 10 以上,则在 chars 数组中会被拆分为多个字符。

请在 修改完输入数组后 ,返回该数组的新长度。

你必须设计并实现一个只使用常量额外空间的算法来解决此问题

3.相关算法

双指针:

算法的思路是,使用两个指针 i 和 j,分别指向当前字符和待写入的位置。使用一个计数器 count 记录当前字符出现的次数。

遍历整个字符数组,对于每个字符,如果它和前一个字符相同,则将计数器加 1;否则,将前一个字符和它出现的次数写入数组,并将指针 j 移动到下一个位置,继续处理下一个字符。

计数器:

算法的思路是,使用一个计数器 count 记录当前字符出现的次数,使用一个指针 j 来记录当前待写入的位置。遍历整个字符数组,对于每个字符,如果它和前一个字符相同,则将计数器加 1;否则,将前一个字符和它出现的次数写入数组,并将指针 j 移动到下一个位置,继续处理下一个字符。

4.本题主要思路

本题是用双指针的解法,创建两个指针i,j分别指向当前字符和替换的位置,使用一个计数器记录当前字符串出现的个数,若个数大于一,则将其替换,否则i++进入下一个字符的处理,最后的到相应的结果返回

5.源码分析

public int compress(char[] chars) {
    int n = chars.length;					// 1
    int i = 0, j = 0;						// 2
    while (i < n) {										
        int cnt = 1;						// 3
        while (i < n - 1 && chars[i] == chars[i + 1]) {		// 4
            cnt++;												
            i++;
        }
        chars[j++] = chars[i];					// 5
        if (cnt > 1) {							
            String str = String.valueOf(cnt);			// 6
            for (int k = 0; k < str.length(); k++) {		
                chars[j++] = str.charAt(k);					
        }
        i++;												// 8
    }
    return j;												// 9
}
  1. 获取chars数组的长度,方便后面循环;
  2. 创建并初始化两个指针变量;
  3. 创建字符串计数器;
  4. 当前后两个字符串相等时,计数器+1,偏移指针往后偏移;
  5. 偏移指针指向了不同的字符串,将其写入待写入的位置,待写入的指针往后一个单位;
  6. 当字符计数器大于1是,将其转化为字符串;
  7. 将该字符串切成一个个字符写入待写入位置【字符的数量可能大于10,这时要将十位和个位分别存入数组中】;
  8. 偏移指针往后偏移;
  9. 循环结束最后返回压缩后数组元素的的个数。