给定一组字符,使用原地算法将其压缩。
压缩后的长度必须始终小于或等于原数组长度。
数组的每个元素应该是长度为1 的字符(不是 int 整数类型)。
在完成原地修改输入数组后,返回数组的新长度。
进阶:
你能否仅使用O(1) 空间解决问题?
思路:
用一个迭代器t来遍历字符数组,num表示重复的字符的个数,len表示最后的长度,temp表示插入数字的次数
如果*t==*(t+1)即2个字符相等的话,num++计算重复的字符的个数,并chars.erase(t+1);把下一个字符从字符串数组中删掉
如果不相等的话,那就依据num的值在t后面插入重复的数字,并且迭代器t依据temp往后移动
一直到遍历完字符串数组为止
代码:
class Solution {
public:
int compress(vector<char>& chars) {
if(chars.size()==1)
return 1;
vector<char>::iterator t=chars.begin();
int num=1,len=0,temp=0;
while(1)
{
if(*t==*(t+1)) //*t和*(t+1)相等的情况
{
num++;
chars.erase(t+1);
if(t==chars.end()-1) //如果t已经到了最后一个字符,则执行插入数字后跳出循环
{
while(num)
{
chars.insert(t+1,num%10+48);
num/=10;
temp++;
}
len+=temp+1;
break;
}
}
else //*t和*(t+1)不相等且重复字符个数>1的情况
{
if(num!=1)
{
while(num)
{
chars.insert(t+1,num%10+48); //每次取num的个位数插入到字符数组中
//因为数字转字符比较麻烦,所以直接依据数字计算出对应字符的ASCII码,再进行插入就可以
num/=10; //取完num的个位后把后面的位往前面移动
temp++; //计算插入的数字的数量
}
t=t+temp+1; //迭代器依据计算插入的数字的数量往后面移动
len+=temp+1; //返回的长度依据插入的数字的数量更新
temp=0; //执行完插入数字后temp和num重新归位
num=1;
}
else //*t和*(t+1)不相等且重复字符个数=1的情况
{
len++;
t++;
}
}
if(t==chars.end()-1) //如果是最后一个字符,则更新len之后跳出循环
{
len++;
break;
}
}
return len;
}
};
效果: