题目链接:https://leetcode-cn.com/problems/string-compression/
题意:
给你一个字符数组 chars ,请使用下述算法压缩:
从一个空字符串 s 开始。对于 chars 中的每组 连续重复字符 :
如果这一组长度为 1 ,则将字符追加到 s 中。
否则,需要向 s 追加字符,后跟这一组的长度。
压缩后得到的字符串 s 不应该直接返回 ,需要转储到字符数组 chars 中。需要注意的是,如果组长度为 10 或 10 以上,则在 chars 数组中会被拆分为多个字符。请在 修改完输入数组后 ,返回该数组的新长度。
你必须设计并实现一个只使用常量额外空间的算法来解决此问题。
方法一:利用新向量存储最终结果,在计算字符个数的时候,另开一个暂存向量存储数字,因为循环是从低位到高位,该向量需要反转一次,反转后的结果插入新向量中,最后新向量再赋值给chars
class Solution {
public:
int compress(vector<char>& chars) {
int size = chars.size();//存储数组长度
char pre = chars[0];//存储前一个字符
int len = 1;//记录相同字符的长度
int ans = 0;//记录最后的长度
vector<char> vct;//用于存储新数组
for(int i=1;i<size;i++)//枚举每个字符
{
if(chars[i]!=pre)//当前字符不等于前一个字符
{
if(len==1)
{
vct.emplace_back(pre);//插入元素
ans++;//如果刚好前面只有一个,就加上字符,不加数字
}
else//否则
{
ans++;//先加上一个字符
vct.emplace_back(pre);//插入元素
vector<char> tmp;//暂存数字结果
while(len)//再加上字符长度
{
ans++;//更新结果
tmp.emplace_back(len%10+'0');
len/=10;//检查字符长度
}
reverse(tmp.begin(),tmp.end());
vct.insert(vct.end(),tmp.begin(),tmp.end());//tmp插入到vct中
}
pre = chars[i];//更新前一个字符
len = 1;//更新相同字符的长度
}else
{
len++;//否则长度自加
}
}
if(len!=0)//最后一次还有剩
{
if(len==1)
{
vct.emplace_back(chars[size-1]);//插入元素
ans++;//如果刚好前面只有一个,就加上字符,不加数字
}
else//否则
{
ans++;//先加上一个字符
vct.emplace_back(chars[size-1]);//插入元素
vector<char> tmp;//暂存数字结果
while(len)//再加上字符长度
{
ans++;//更新结果
tmp.emplace_back(len%10+'0');
len/=10;//检查字符长度
}
reverse(tmp.begin(),tmp.end());
vct.insert(vct.end(),tmp.begin(),tmp.end());//tmp插入到vct中
}
}
chars.clear();//清空chars
chars.insert(chars.begin(),vct.begin(),vct.end());//插入vct
return ans;//返回答案
}
};
方法二:双指针
class Solution {
public:
int compress(vector<char>& chars) {
int size = chars.size();//存储数组长度
int left = 0, write = 0;//双指针,左侧坐标,写指针
for(int i=0;i<size;i++)//枚举所有元素
{
if(i==size-1||chars[i]!=chars[i+1])//如果该元素刚好是最后一个,或者出现了一个不一样的元素
{
chars[write] = chars[i];//存下当前的字符
write++;//右侧坐标右移
int num = i-left+1;//记录长度
if(num>1)//当长度大于1时
{
int start = write;//定义起始位置
while(num)//当长度不为0时
{
chars[write] = num%10+'0';//写入字符
write++;//坐标右移
num/=10;//更新下一位
}
reverse(&chars[start],&chars[write]);//颠倒这个区间里的元素
}
left = i+1;//更新长度
}
}
return write;//返回答案
}
};