压缩字符串
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
}
- 获取chars数组的长度,方便后面循环;
- 创建并初始化两个指针变量;
- 创建字符串计数器;
- 当前后两个字符串相等时,计数器+1,偏移指针往后偏移;
- 偏移指针指向了不同的字符串,将其写入待写入的位置,待写入的指针往后一个单位;
- 当字符计数器大于1是,将其转化为字符串;
- 将该字符串切成一个个字符写入待写入位置【字符的数量可能大于10,这时要将十位和个位分别存入数组中】;
- 偏移指针往后偏移;
- 循环结束最后返回压缩后数组元素的的个数。