题目描述:给定一组字符,使用原地算法将其压缩。压缩后的长度必须始终小于或等于原数组长度。数组的每个元素应该是长度为 1 的字符(不是 int 整数类型)。在完成原地修改输入数组后,返回数组的新长度。
示例 1:
输入:["a","a","b","b","c","c","c"]
输出:返回6,输入数组的前6个字符应该是:["a","2","b","2","c","3"]
示例 2:
输入:["a"]
输出:返回1,输入数组的前1个字符应该是:["a"]
示例 3:
输入:["a","b","b","b","b","b","b","b","b","b","b","b","b"]
输出:返回4,输入数组的前4个字符应该是:["a","b","1","2"]。
注意:所有字符都有一个ASCII值在[35, 126]区间内。1 <= len(chars) <= 1000。
解析:三个变量,其中两个用来移动寻找一个字母出现的起始位置,另一个表示压缩进度。
i 指向字母的开始位置,j 不断寻找与 i 所表示的字母不同的位置,遍历过程中要注意 j 可能会增加到数组末尾,如数组 ['a','a'],所以当遇到以下两种情况时就可以进行压缩:
- j == chars.length;
- chars[i] != chars[j];
找到后 count = j-i 就是该字母出现的次数:
- 若等于 1 ,则不用在压缩的数组中添加次数 1
- 大于 1 时需要添加次数,但是由于一个位置只能放一个小于 10 的数字,因此需要判断次数的数量级。
class Solution {
public int compress(char[] chars) {
int i = 0,j = 0,len = 0;
while(j < chars.length){
if(chars[i] == chars[j]){
j++;
}
if(j == chars.length || chars[i] != chars[j]){
int count = j - i;
chars[len++] = chars[i];
if(count > 1) {// 出现一次以上才会将次数添加进去
int div = 1000;// 确认该字母出现次数的数量级
while (count / div == 0) {
div /= 10;
}
while (div > 0) {//不能使用 count 作为结束条件,如果 count = 10,就会出错。
chars[len++] = (char) (count / div + '0');
count = count % div;
div /= 10;
}
}
i = j;
}
}
return len;
}
}