
解题思路:
双指针
假如数组长度小于等于1,直接返回数组长度就可以了。
声明快慢指针fast,slow,指向数组头。
fast往后走,假如fast指向的字符等于slow指向的字符,不需要做处理,fast继续往后走。
直到fast指向的字符不等于slow指向的字符,停下,之后fast都要指向这个位置,用fast-slow(因为vector的迭代器是原生指针,所以可以直接进行-操作)得到slow和fast的距离count,即slow指向的字符重复出现的次数count。
我们现在要做的是保留一个slow指向的字符;假如count>1的话,再在后面跟上重复的次数。
删除:
那么我们只需要删除[slow+1,fast)这个范围(左闭右开)的元素即可,erase的返回值是最后一个删除元素的后一个元素的迭代器。
最后fast的位置就是slow的后一个位置。
插入:
接下来插入重复次数,用to_string(count)先转换成string字符串,然后一个一个插入fast的这个位置,原来的fast将后移一个位置,insert返回插入元素的迭代器的位置。
每次插入一个字符,要让fast+1,回到原来fast的位置。
fast的位置永远指向与slow字符不同的那个字符。
完成一次压缩,更新slow=fast。
最后:边界条件
假如fast到末尾了,退出循环了;假如没到末尾,fast向后移动一格。
假如这时候fast到末尾了,说明要进行压缩操作,并且压缩操作完成后将不再进入while循环。
所以 fast!=chars.end() 这个条件就是用来处理fast到了end这个情况的。
class Solution {
public:
int compress(vector<char>& chars) {
int n=chars.size();
if(n<=1)return n;
//设置快慢指针
auto fast=chars.begin(),slow=chars.begin();
while((fast++)!=chars.end()){
//fast走一步,假如字符相同,继续向后走
if(fast!=chars.end()&&(*fast==*slow))
continue;
//否则停下来,记录字符和个数,slow到fast的位置
int count=fast-slow;
//假如count>1,就要加数字
if(count!=1){
fast=chars.erase(slow+1,fast); //保留slow一个字符,删掉[slow+1,fast)的所有重复元素,记得更新迭代器fast的位置
string str=to_string(count); //count转成string类型,方便插入chars
for(int i=0;i<str.size();++i){
fast=chars.insert(fast,str[i]);//字符插入到fast这个位置,返回新插入的元素的迭代器
++fast; //而原来的fast向后移动了,要找到原来的fast的位置,所以++fast
}
}
slow=fast; //更新slow
}
return chars.size();
}
};
该博客讨论了一种利用双指针技巧解决数组字符压缩问题的方法。在C++中,通过设置快慢指针,遍历数组并比较字符,删除重复元素,插入重复次数,实现了字符数组的压缩。算法涉及迭代器操作、字符串转换和容器动态修改等概念。
1804

被折叠的 条评论
为什么被折叠?



