20.4.13 压缩字符串 简单
时间复杂度O(n),空间复杂度O(1)
题目
给定一组字符,使用原地算法将其压缩。
压缩后的长度必须始终小于或等于原数组长度。
数组的每个元素应该是长度为1 的字符(不是 int 整数类型)。
在完成原地修改输入数组后,返回数组的新长度。
进阶:
你能否仅使用O(1) 空间解决问题?
示例 1:
输入:
["a","a","b","b","c","c","c"]
输出:
返回6,输入数组的前6个字符应该是:["a","2","b","2","c","3"]
说明:
"aa"被"a2"替代。"bb"被"b2"替代。"ccc"被"c3"替代。
示例 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"]。
说明:
由于字符"a"不重复,所以不会被压缩。"bbbbbbbbbbbb"被“b12”替代。
注意每个数字在数组中都有它自己的位置。
注意:
所有字符都有一个ASCII值在[35, 126]区间内。
1 <= len(chars) <= 1000。
解题思路
- 第一次见这种题目,没有太清楚题意,改了很多次才懂。压缩数组其实就是,把相同的合并,但是不是全部相同都合并,比如[a,a,b,b,a,a],不是压成[a,4,b,2],我一开始还先排序了,然后做错了。
- 双指针,一个指针遍历数组,一个指针更改数组,更改一定不会比遍历快,大部分情况更改指针都在遍历指针后面改数。
代码思路
- 排除特殊情况;
- 指针index为遍历指针,指针curr为更改指针,也是最后输出的压缩长度,因为改到哪长度就定在哪;
- 遍历开始,用count统计从当前字符到不相同字符之前的数目,chars[curr],当前更改的位置要先变为当前字符;
- while循环统计相同字符长度;
- 三个判断将相同字符的数量分情况插入数组,同时不断更新更改指针curr的位置;
- 用curr指针更新遍历指针index的位置,index会指着下一个字符的位置,继续循环。
代码
class Solution {
public:
int compress(vector<char>& chars) {
if(chars.size() == 0) return 0;
int index=0;
int curr=0;
for(; index<chars.size();){
int count=1;
chars[curr]=chars[index];
while(index+count<chars.size() && chars[index]==chars[index+count]) count++;
if(count>9){
chars[curr+1]=count/10+'0';
chars[curr+2]=count%10+'0';
curr+=3;
}
else if(count>1){
chars[curr+1]=count+'0';
curr+=2;
}
else curr+=1;
index+=count;
}
return curr;
}
};