面试 | 双法妙解压缩字符串【遍历统计 + 双指针】

news2024/11/28 12:54:41

在这里插入图片描述

一、题目描述

原题传送门

在这里插入图片描述

二、思路分析

首先我们来分析一下解决本题所需要的思路

  • 题目的意思很简单,就是统计原本的字符串中的每个字符出现的次数,然后以【字符,出现的次数】这样的结构来字符串,以起到一个压缩的效果,那么对于这样的结构,详细很多力友都会想到map这个键值对的结构,但是认真查看题目本身的话却发现我们不可以用这种结构

输入:“aabcccccaaa”
输出:“a2b1c5a3”

  • 我们以第一个为例,从左往右分别是2个a、1个b、5个c和3个a,此时若我们通过map去做遍历的话,开头的【a】和结尾的【a】就会合并在一起变为5个a,那么最后在拼接字符串的时候就会出现问题,所以map的这种结构我们是不能使用
unordered_map<char, int> count
for(char c : S)
{
    count[c]++;
}

接下去就来看看下面的两种做法👇

Way1 : 遍历统计

  • 首先是第一种方法,既然题目给到了一个字符串,那我们就去遍历它并进行一个统计,那既然是统计某个字符出现了多少次的话,就需要有一个字符变量去记录,这里我们拿ch首先保存下第一个字符,后面遍历的时候再做更新
char ch = S[0]; 
  • 当然,我们还需要一个计数器cnt
  • 接下去这段逻辑就是在遍历这个字符串的同时去统计里面的每个字符出现了多少次,如果当前所遍历的字符和ch是相同的话,计数器cnt就去做一个累加,如果不相同的话,我们就可以去拼接字符串了,ch即为当前所需要统计的字符,cnt即为这个字符所出现的次数,不过我们要使用到C++里的一个库函数叫做 to_string ,不清楚的力友可以先去了解一下
  • 当这个字符拼接完后,我们就要去统计下一个字符了,这个时候就要更新【ch】和【cnt】了
string compressStr = "";
for(int i = 1;i < sz; ++i)
{
    if(S[i] == ch){
        cnt++;      // 如果当前所遍历到的字符与需统计字符相同的话,则计数器 + 1
    }else{
        compressStr += ch + to_string(cnt);
        ch = S[i];
        cnt = 1;
    }
}
  • 最后呢,在遍历结束之后我们还需要在去做一个拼接,因此当最后遍历最后跳出循环并没有把最后一个字符给拼接上去
// 最后在遍历结束后添加最后一个字符的统计结果
compressStr += ch + to_string(cnt);
  • 当字符拼接完后,就将其返回,但是题目中说到如果压缩之后的字符串长度比原字符串还长的话,就返回原先的串
return compressStr.size() >= sz ? S : compressStr;
  • 不过这里还有隐藏的一个测试案例,我们应该要考虑到压缩后的字符串和原串相等的情况,也是需要返回原串的

1.jpg

代码展示:

class Solution {
public:
    string compressString(string S) {
        int sz = S.size();

        if(sz == 0)
            return S;   // 如果是空串的话,则返回自己本身

        string compressStr = "";
        int cnt = 1;        // 统计每一个字符个数
        char ch = S[0];     // 记录当前所要统计的字符

        // 循环直接从1开始即可,第一个字符一定算一个
        for(int i = 1;i < sz; ++i)
        {
            if(S[i] == ch){
                cnt++;      // 如果当前所遍历到的字符与需统计字符相同的话,则计数器 + 1
            }else{
                compressStr += ch + to_string(cnt);
                ch = S[i];
                cnt = 1;
            }
        }
        // 最后在遍历结束后添加最后一个字符的统计结果
        compressStr += ch + to_string(cnt);

        // 三目运算符:若是压缩后的字符串长度 >= 原字符串的长度,则返回原串
        return compressStr.size() >= sz ? S : compressStr;
    }
};

最后展示一下AC后的结果

2.jpg

Way2 : 双指针

接下去要介绍的就是另一种解法,此解法来自 K神 很是巧妙,力友可以学习一下这种解法

图解分析

总体思路概述:

  • 这种方法很巧妙地利用了双指针,首先让指针ij指向当前字符串的首位,然后让指针j不断地先后遍历,比较 s[i] 和 s[j] 的的字符是否相同,若是相同的话则让j继续后移,直到二者不相同为止。
  • 此时我们便去计算当前的这个字符出现了多少次,使用【指针 - 指针】的办法算出来。然后再去统计下一个字符的位置,此时让i移动到j的位置来即可,因为二者不相同后j一定指向了一个新的字符
  • 然后继续重复上面的逻辑就可以了,直到这个字符串遍历完之后也就压缩完了

然后我们就根据 示例1 来分布细述一下

  • 首先双指针都指向字符串的首位置

3.jpg

  • 然后因为【a = a】,所以j++i不动

4.jpg

  • 继续还是一样,【a = a】,j++

5.jpg

  • 那么接下来【a != b】,遇到不相等了,此时我们就需要去统计当前这个字符所出现的此处,使用j - i就可以计算得到,那么此时就可以将这结果追加到压缩后的字符串中了。接下去便是更新指针i的位置到j这里来,进行下一个字符串个数的统计

6.jpg

  • 接下去就开始统计字符b出现的个数了,但是呢在比较了一次够就不相等了,于是立马就得出这个字符只出现了一次,步骤和上述一样

7.jpg

  • 接下去就是字符【c】了,利用j - i可以算出其出现了5次,继续拼接到压缩串compressStr中

8.jpg

  • 最后当这个串遍历完之后,因为没有再进入循环了,所以我们在最后还要拼接一次

9.jpg

  • 最后的话当我们要返回结果的时候还需要比较一下压缩后的串和原串的长度,只有当压缩后的串来得短的时候才可返回,否则一律返回原串

10.jpg

代码展示:

class Solution {
public:
    string compressString(string S) {
        if(S.size() == 0)   return S;
        int i = 0, j = 0;
        string compressStr = "";

        while(j < S.size())
        {
            // 持续比较双指针上的位置,直到不相同为为止
            while(S[i] == S[j]){
                j++;
            }
            compressStr += S[i];
            compressStr += to_string(j - i);
            i = j;      // i换位到新字符的位置
        }
        
        return compressStr.size() >= S.size() ? S : compressStr; 
    }
};

最后从提交的结果就可以看出效率提升了不少 ↑

11.jpg

认真看完上面这个例子后,其他的示例相信你一定也能推敲出来🌹

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/779861.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Fiddler抓包实战,彻底打通接口测试(二)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 请求查看 Inspec…

Spring简述IOC入门案例

文章目录 Spring学习笔记Spring&#xff1a;Spriing framework:IoC&#xff08;控制反转&#xff09;对象的创建控制权由程序转移到外部&#xff1a;DI( Dependency Injection )依赖注入&#xff1a; IoC入门案例&#xff1a;项目结构&#xff1a;applicationContext.xml:bookD…

mysql-5.7 Linux安装教程

通过命令下载&#xff1a; 下载到 cd /usr/local 这个路径下 wget http://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.36-linux-glibc2.12-x86_64.tar.gz 解压&#xff1a; tar -zxvf mysql-5.7.36-linux-glibc2.12-x86_64.tar.gz 将解压的 重命名 为mysql mv mysql-5…

B/S架构的云HIS系统源码 技术架构:Angular+Nginx+ Java+Spring

基于云计算技术的B/S架构的HIS系统源码&#xff0c;为基层医疗机构提供标准化的、信息化的、可共享的医疗信息管理系统&#xff0c;实现医患事务管理和临床诊疗管理等标准医疗管理信息系统的功能。系统利用云计算平台的技术优势&#xff0c;建立统一的健康档案存储平台&#xf…

seatunnel hive source 未设置分隔符导致多个字段合并成一个的问题定位解决

seatunnel hive source 未设置分隔符导致多个字段没有切分全保存在一个字段中了,翻看源码发现分隔符是是通过delimiter设置的,只要设置这个delimiter","就可以了。 设置这个属性 delimiter“,” 他的默认值是\u0001,如果没有设置delimiter属性则会根据文件类型判断…

Flink写入数据到Doris

文章目录 1.Doris建表2.Doris依赖3.Bean实体类4.Doris业务写入逻辑5.测试写入类6.发送数据 1.Doris建表 Doris中建表 CREATE TABLE IF NOT EXISTS demo.user (id INT NOT NULL,name VARCHAR(255),age INT ) DISTRIBUTED BY HASH(id) PROPERTIES ("replication_num&qu…

前端工程化第三章:webpack5基础(下)

文章目录 1. TypeScript支持&#xff08;ts-loader&#xff09;1.1. ts-loader1.1.1. webpack.config.js1.1.2. tsconfig.json1.1.3. src/index.ts 1.2. 使用babel-loader将ts转换为js1.2.1. webpack.config.js1.2.2. src/index.ts 2. 代码规范检查&#xff08;Eslint&#xff…

「深度学习之优化算法」(十八)头脑风暴算法

1. 头脑风暴算法简介 (以下描述,均不是学术用语,仅供大家快乐的阅读)   可能大家对“头脑风暴”这个词不怎么熟,毕竟是外来词汇,其大概含义就是分组讨论,畅所欲言。   头脑风暴算法(Brain Storm Optimization)是根据人们进行“头脑风暴”讨论困难问题的解决方案的过…

RabbitMQ消息可靠性问题及解决

说明&#xff1a;在RabbitMQ消息传递过程中&#xff0c;有以下问题&#xff1a; 消息没发到交换机 消息没发到队列 MQ宕机&#xff0c;消息在队列中丢失 消息者接收到消息后&#xff0c;未能正常消费&#xff08;程序报错&#xff09;&#xff0c;此时消息已在队列中移除 …

Android WiFi框架概览

概览 Android 提供默认 Android 框架实现&#xff0c;其中包括对各种 WLAN 协议和模式的支持&#xff0c;这些协议和模式包括&#xff1a; WLAN 基础架构 (STA)网络共享模式或仅限本地模式下的 WLAN 热点 (Soft AP)WLAN 直连&#xff08;点对点&#xff09;WLAN 感知 (NAN)WL…

3.19 Bootstrap 面板(Panels)

文章目录 Bootstrap 面板&#xff08;Panels&#xff09;面板标题面板脚注带语境色彩的面板带表格的面板带列表组的面板 Bootstrap 面板&#xff08;Panels&#xff09; 本章将讲解 Bootstrap 面板&#xff08;Panels&#xff09;。面板组件用于把 DOM 组件插入到一个盒子中。创…

Python采集某网站小视频内容, m3u8视频内容下载

目录标题 前言环境使用:模块使用:代码实现步骤代码展示尾语 前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 环境使用: python 3.8 运行代码 pycharm 2021.2 辅助敲代码 模块使用: import requests >>> pip install requests 内置模块 你安装好python环境就…

【机器学习】支持向量机SVM入门

优化目标 相较于之前学习的线性回归和神经网络&#xff0c;支持向量机&#xff08;Supprot Vector Machine&#xff0c;简称SVM&#xff09;在拟合复杂的非线性方程的时候拥有更出色的能力&#xff0c;该算法也是十分经典的算法之一。接下来我们需要学习这种算法 首先我们回顾…

ffplay播放器剖析(4)----音频输出和音频重采样流程

文章目录 1. 音频输出模块1.1 音频输出流程1.2 音频输出模型图 2. 打开SDL音频设备audio_open详解sdl_audio_callbackaudio_decode_frame 3. 音频重采样样本补偿 1. 音频输出模块 1.1 音频输出流程 打开SDL音频设备,设置参数启动SDL音频设备播放SDL音频回调函数读取数据,也就…

虚拟仿真实验室未授权获取账号密码

你应该在以后短暂的岁月里&#xff0c;真正活的不负众爱 漏洞描述 虚拟仿真实验室存在未授权访问漏洞&#xff0c;通过访问构造的Url可以获取敏感信息 漏洞复现 访问漏洞url&#xff1a; /admin/student/studentlist.html?page1成功获取所有用户的账号密码信息 文笔生疏…

遥感目标检测(2)--SCRDet

目录 一、概述 二、三个挑战 三、网络结构 1、SF-Net 2、MDA-Net&#xff08;Multi-Dimensional Attention Network&#xff09; 3、Rotation Branch 四、损失函数 五、实验 一、概述 SCRDet&#xff08;Towards More Robust Detection for Small,Cluttered and Rotate…

实验数据origin作图使用经验总结

使用Origin绘制实验数据图表时&#xff0c;可以遵循以下经验总结&#xff1a; 选择合适的图表类型&#xff1a; 根据实验数据的性质和目的&#xff0c;选择合适的图表类型&#xff0c;例如散点图、折线图、柱状图、饼图等。确保图表类型能够清晰地展示数据趋势和关系。 规范坐…

jenkins中运行python脚本时,报错:collecting ... collected 0 items

【问题描述】&#xff1a;jenkins在windows环境下运行python脚本时总是报collecting … collected 0 items 【问题定位】&#xff1a;jenkins工作目录和python文件目录不一样导致 【解决办法】&#xff1a;需要先把路径切换到项目目录下&#xff0c;再进行运行xxx.py文件&…

zabbix钉钉报警

登录钉钉客户端,创建一个群,把需要收到报警信息的人员都拉到这个群内. 然后点击群右上角 的"群机器人"->"添加机器人"->"自定义", 记录该机器人的webhook值。 添加机器人 在钉钉群中&#xff0c;找到只能群助手 添加机器人 选择自定义机…

springboot 根据不同环境 ,配置不同日志输出路径

logback-spring.xml<?xml version"1.0" encoding"UTF-8"?> <!-- scan&#xff1a;当此属性设置为true时&#xff0c;配置文件如果发生改变&#xff0c;将会被重新加载&#xff0c;默认值为true。 scanPeriod&#xff1a;设置监测配置文件是否有…