C++ 实现字符数组压缩:一个简单高效的方法
在本文中,我们将讨论如何在C++中压缩字符数组,使每组连续重复字符在数组中只保留一个字符,并记录其重复次数。这是一个经典的算法问题,常常出现在面试中。我们将通过逐步分析解决思路和代码实现,帮助大家理解这一问题的解决方法。
问题描述
给你一个字符数组 chars,请使用如下算法进行压缩:
- 从一个空字符串
s开始。对于chars中的每组连续重复字符:- 如果这一组长度为1,则将字符追加到
s中。 - 否则,追加字符,并跟随其重复的次数。
- 如果这一组长度为1,则将字符追加到
压缩后得到的字符串 s 不应直接返回,而是需要转储到字符数组 chars 中。同时,你需要返回修改后数组的长度。
示例
- 输入:
chars = ['a', 'a', 'b', 'b', 'c', 'c', 'c']
输出:返回 6 ,输入数组的前 6 个字符应该是:['a', '2', 'b', '2', 'c', '3'] - 输入:
chars = ['a']
输出:返回 1 ,输入数组的前 1 个字符应该是:['a'] - 输入:
chars = ['a', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b']
输出:返回 4 ,输入数组的前 4 个字符应该是:['a', 'b', '1', '2']
解决思路
为什么使用 while 循环而不是 for 循环?
在这个问题中,我们需要遍历 chars 数组,并统计每个字符连续出现的次数。使用 while 循环的原因是,我们需要在循环中进行迭代,同时在判断连续字符时增加索引 i。具体来说,当遇到连续字符时,我们需要在 i++ 之前进行判断和操作,这使得 while 循环更为合适。
write++:简单移动写入位置
为了在原地压缩字符数组,我们使用一个变量 write 来表示当前写入位置。每当我们确定一个字符及其重复次数时,先写入字符,然后使用 write++ 简单地移动写入位置。这样既能确保字符顺序正确,又能避免复杂的索引管理。
to_string 的巧妙使用
当某个字符重复次数超过1时,我们需要将次数转换为字符并写入数组。这里使用 to_string 将整数转换为字符串,然后使用 foreach 循环将每个字符写入 chars 数组。这样做既简洁又高效。
返回 write 的原因
最后,我们返回 write 作为压缩后数组的长度。尽管 chars 数组的总长度未变,但 write 位置代表了真实的数组内容长度,确保结果正确。
代码实现
class Solution {
public:
int compress(vector<char>& chars) {
int n = chars.size();
if (n == 1)
return 1;
int write = 0; // 写入位置
int i = 0; // 读取位置
while (i < n) {
char current_char = chars[i];
int count = 0;
// 计算连续重复字符的数量
while (i < n && chars[i] == current_char) {
i++;
count++;
}
// 写入当前字符
chars[write++] = current_char;
// 写入计数(如果大于1)
if (count > 1) {
for (char c : to_string(count)) {
chars[write++] = c;
}
}
}
return write;
}
};
详细解析
-
初始化变量:
int write = 0; // 写入位置 int i = 0; // 读取位置 -
遍历
chars数组:while (i < n) { char current_char = chars[i]; int count = 0; // 计算连续重复字符的数量 while (i < n && chars[i] == current_char) { i++; count++; } // 写入当前字符 chars[write++] = current_char; // 写入计数(如果大于1) if (count > 1) { for (char c : to_string(count)) { chars[write++] = c; } } } -
返回新数组的长度:
return write;
通过以上的修改,代码能够正确处理字符的连续重复,并将其压缩后写回到原数组中,同时返回压缩后数组的新长度。
C++字符数组压缩技巧
8442

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



