C++ 实现字符数组压缩:一个简单高效的方法【字符串压缩、双指针】

C++字符数组压缩技巧

C++ 实现字符数组压缩:一个简单高效的方法

443. 压缩字符串 - 力扣(LeetCode)

在本文中,我们将讨论如何在C++中压缩字符数组,使每组连续重复字符在数组中只保留一个字符,并记录其重复次数。这是一个经典的算法问题,常常出现在面试中。我们将通过逐步分析解决思路和代码实现,帮助大家理解这一问题的解决方法。

问题描述

给你一个字符数组 chars,请使用如下算法进行压缩:

  1. 从一个空字符串 s 开始。对于 chars 中的每组连续重复字符:
    • 如果这一组长度为1,则将字符追加到 s 中。
    • 否则,追加字符,并跟随其重复的次数。

压缩后得到的字符串 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;
    }
};

详细解析

  1. 初始化变量

    int write = 0; // 写入位置
    int i = 0; // 读取位置
    
  2. 遍历 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;
            }
        }
    }
    
  3. 返回新数组的长度

    return write;
    

通过以上的修改,代码能够正确处理字符的连续重复,并将其压缩后写回到原数组中,同时返回压缩后数组的新长度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值