【算法练习Day7】反转字符串替换空格反转字符串中的单词左旋转字符串

在这里插入图片描述

​📝个人主页:@Sherry的成长之路
🏠学习社区:Sherry的成长之路(个人社区)
📖专栏链接:练题
🎯长路漫漫浩浩,万事皆有期待

文章目录

  • 反转字符串
  • 反转字符串 II
  • 替换空格
  • 反转字符串中的单词
  • 左旋转字符串
  • 总结:

反转字符串

344. 反转字符串 - 力扣(LeetCode)
在这里插入图片描述

这道题思路并不难,甚至可以直接reverse调用库函数来一步到位(但是我之前并不知道这个库函数)reverse(开始地址,结束地址),可以将一个字符串从前到后依次反转,也就是第一个元素跑到最后一位,第二位元素跑到倒数第二个位置上,以此类推,不过直接使用reverse就失去了做题的意义了。

于是有了另一种思路:用双指针的思路,一层遍历,将字符串反转,与其说是换一种思路,倒不如说是reverse库函数的一种实现,代码如下

class Solution {
public:void reverseString(vector<char>& s) {int l=s.size();for(int i=0,j=l-1;i<l/2;i++,j--)swap(s[i],s[j]);}
};

反转字符串 II

541. 反转字符串 II - 力扣(LeetCode)
在这里插入图片描述

反转字符串II这题,乍一看好像真的比上一道要难不少,要求很多,不知道该如何下手,但是只要知道思路了,代码很容易实现,题目大意是给一个字符串和一个整数k,每隔2k个数字,就反转前k个字符,如果剩余字符不足2k但是大于或等于k个反转前k个剩余保持不变(等待再次判断),如果小于k个全部反转。这道题的精髓在于控制一个变量,使它一次走2k步,在循环中用if来调整其余的判断部分,这样可以使代码变得富有规律,且代码不易冗余。

class Solution {
public:string reverseStr(string s, int k) {for(int i=0;i<s.length();i+=2*k){if(i+k<=s.length())//<=十分重要reverse(s.begin()+i,s.begin()+i+k);elsereverse(s.begin()+i,s.end());}return s;}
};

在代码中我们可以看到,进入循环我们直接判断剩余的元素个数满足哪一个条件,请注意,字符反转与否,与剩余字符有着很大的关联!不要将题目理解错误,我们在if里面包含了上述题目中,剩余字符很多(可以继续遍历2k个)和剩余字符大于k但不足2k个两种情况,也就是说以上两种情况,都是可以正常反转k个,如果到了else那就说明不足k个了,只能将后面元素全部反转了。理清思路了,代码还是很好写的。

替换空格

替换空格 - 牛客

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
示例 1: 输入:s = “We are happy.”
输出:"We%20are%20happy.

这道也是之前在牛客上做过的一道题,只是忘记了思路。后来看了题解想了起来,题目思路不算难,但是没有做过基本很难做出来,题目要求是给你一个字符串,将字符串中空格位置区域替换成%20的符号,思路是遍历一遍字符串查找有多少个空格,在字符串后面补充空格数*2,因为本来有一个空格,所以只需乘以2就足够了,然后用双指针方法,一个指针指向新空间末尾,一个指针指向字符串末尾,遇到字符就复制过来,遇到空格填充%20,整体代码没有难度,只是思路有点难想。

class Solution {
public:string replaceSpace(string s) {int len1=s.size();int count=0;// 统计空格的个数for(int i=0;i<len1;i++){if(s[i]==' ')count++;}// 扩充字符串s的大小,也就是每个空格替换成"%20"之后的大小s.resize(s.size()+2*count);int len2=s.size();// 从后先前将空格替换为"%20"for(int i=len2,j=len1;i>j;i--,j--){if(s[j]==' '){s[i]='0';s[i-1]='2';s[i-2]='%';i-=2;}elses[i]=s[j];}return s;}
};

时间复杂度: O(n)
空间复杂度: O(1)

反转字符串中的单词

151. 反转字符串中的单词 - 力扣(LeetCode)
在这里插入图片描述

这道题目leetcode给出中等,这道题实际上包含了字符串的很多操作,十分繁琐,说是困难题应该也不为过,题目要求将给定字符串去除除了每个单词之间的空格之外的所有空格,并且将整个字符串反转,这个字符串的前后和中间都有可能出现多个空格,这是难处理的点,然后还要将字符串内容全部反转(不是将每个字符反转,而是将单词反转)。

class Solution {
public:void reverse(string& s,int start,int end){//翻转,区间写法:左闭右闭 []for(int i=start,j=end;i<j;i++,j--){swap(s[i],s[j]);}}void removeExtraSpace(string& s)//去除所有空格并在相邻单词之间添加空格, 快慢指针。{int slow=0;for(int i=0;i<s.size();i++){if(s[i]!=' ')//遇到非空格就处理,即删除所有空格。{if(slow!=0){//手动控制空格,给单词之间添加空格。slow != 0说明不是第一个单词,需要在单词前添加空格。s[slow++]=' ';}while(i<s.size()&&s[i]!=' '){ //补上该单词,遇到空格说明单词结束。s[slow++]=s[i++];}}}s.resize(slow);//slow的大小即为去除多余空格后的大小。}string reverseWords(string s) {removeExtraSpace(s);//去除多余空格,保证单词之间之只有一个空格,且字符串首尾没空格。reverse(s,0,s.size()-1);int start=0;//removeExtraSpaces后保证第一个单词的开始下标一定是0。for(int i=0;i<=s.size();i++){if(i==s.size()||s[i]==' '){//到达空格或者串尾,说明一个单词结束。进行翻转。reverse(s,start,i-1);//翻转,注意是左闭右闭 []的翻转。start=i+1;//更新下一个单词的开始下标start}}return s;}
};

最上面的部分,是自定义的交换字符的函数,实现的是前闭后闭的思路,后面的代码主要是删除多余空格,第一个while让fast指针向后走,主要是为了删除开头多余的空格,for循环判断fast指针如果不在第一个位置,说明单词要直接插进去,如果大于0,且前面有空格当前所在位置也有空格,那么说明空格多出来了,需要删掉,这里我们的处理方法与这篇博客中的 移除元素 方法一致。

之后最关键的一步也就是反转字符串,第一次先将字符串整体反转,这样就将整个字符串的所有字符全部反转了,也就是说最后一个字符和第一个字符交换,以此类推。这样最后一个单词的反转就到了第一个位置,倒数第二单词的反转就到了第二个位置,这样的反转已经完成了题目要求的一半了,之后我们的思路就是将每个单词再反转,如何判断呢?

当我们遍历到空格那就说明遍历到一个单词的最后一个字符了,那么我们将这个单词整体反转,如果遍历到最后一个单词,当变量i走到字符最后一个位置说明该反转最后一个单词了,这里的start尤为重要,它标识了一个单词反转的起始位置,而i标识了这个单词的结束位置,遵循先整体反转再局部反转的原则。

时间复杂度: O(n)
空间复杂度: O(1)

左旋转字符串

左旋转字符串 - 牛客
在这里插入图片描述

左旋字符串,就是将该字符串的左边k个字符旋转到字符串后面但是并不将任何部分反转,只不过是将字符调整了位置。

不限制空间复杂度的情况下,最简单的方法就是新开字符串,将后面的部分先复制到新字符串里,紧接着又将前面的部分取下复制到新字符串里就完成了。

class Solution {
public:string LeftRotateString(string str, int n) {int len=str.size();if(len==0){return "";}n%=len;string result;for(int i=n;i<str.size();i++)result.push_back(str[i]);for(int i=0;i<n;i++)result.push_back(str[i]);return result;}
};

如果要求空间复杂度呢?不允许开辟新内存,只能在原字符串操作呢?

我们先将前半部分反转,再将后半部分反转,最后再反转整体,是不是很神奇?可以自行模拟下

class Solution {
public:string LeftRotateString(string str, int n) {int len=str.size();if(len==0){return "";}n%=len;reverse(str.begin(),str.begin()+n);reverse(str.begin()+n,str.end());reverse(str.begin(),str.end());return str;}
};

总结:

今天我们完成了字符串章节的几道题,与之前的一些题有相似之处,相关的思想需要多复习回顾。接下来,我们继续进行算法练习·。希望我的文章和讲解能对大家的学习提供一些帮助。

当然,本文仍有许多不足之处,欢迎各位小伙伴们随时私信交流、批评指正!我们下期见~

在这里插入图片描述

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

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

相关文章

十三,打印辐照度图

上节HDR环境贴图进行卷积后&#xff0c;得到的就是辐照度图&#xff0c;表示的是周围环境间接漫反射光的积分。 现在也进行下打印&#xff0c;和前面打印HDR环境贴图一样&#xff0c;只是由于辐照度图做了平均&#xff0c;失去了大量高频部分&#xff0c;因此&#xff0c;可以…

游戏开发过程中需要注意哪些问题呢?

游戏开发是一个复杂的过程&#xff0c;需要注意多个方面的问题。以下是一些需要特别关注的关键问题&#xff1a; 游戏设计&#xff1a; 确定游戏的核心玩法和目标受众。 制定详细的游戏设计文档&#xff0c;包括角色、关卡设计、游戏机制和故事情节。 技术选择&#xff1a;…

react项目优化

随着项目体积增大&#xff0c;打包的文件体积会越来越大&#xff0c;需要优化&#xff0c;原因无非就是引入的第三方插件比较大导致&#xff0c;下面我们先介绍如何分析各个文件占用体积的大小。 1.webpack-bundle-analyzer插件 如果是webpack作为打包工具的项目可以使用&…

晨控CK-FR08系列读写器与LS可编程逻辑控制器MODBUSRTU连接手册

晨控CK-FR08系列读写器与LS可编程逻辑控制器MODBUSRTU连接手册 晨控CK-FR08是一款基于射频识别技术的高频RFID标签读卡器&#xff0c;读卡器工作频率为13.56MHZ&#xff0c;支持对I-CODE 2、I-CODE SLI等符合ISO15693国际标准协议格式标签的读取。读卡器内部集成了射频部分通信…

开源框架中的责任链模式实践

作者&#xff1a;vivo 互联网服务器团队-Wang Zhi 责任链模式作为常用的设计模式而被大家熟知和使用。本文介绍责任链的常见实现方式&#xff0c;并结合开源框架如Dubbo、Sentinel等进行延伸探讨。 一、责任链介绍 在GoF 的《设计模式》一书中对责任链模定义的&#xff1a;将…

一个关于IntroductionAdvisor的bug

一个关于IntroductionAdvisor的bug public class TestMain {public static void main(String[] args) {// 1. 准备被代理的目标对象People peo new People();// 2. 准备代理工厂ProxyFactory pf new ProxyFactory();// 3. 准备introduction advice,advice 持有需要额外添加的…

Go 围炉札记

文章目录 一、安装二、文档三、使用 一、安装 VSCode 和 CLion 为 Go 开发配置Visual Studio Code | Microsoft Learn VScode下配置Go语言开发环境【2023最新】 基础篇&#xff1a;新手使用vs code新建go项目 vscode里安装Go插件和配置Go环境 GO 笔记 Golang 配置代理 golang…

得物API元数据中心探索与思考

一、背景 目前市面上针对API的管理平台很多&#xff0c;但由于各种客观因素&#xff0c;这些平台的功能都更多聚焦在API文档的消费侧。而对于API文档的生成都非常依赖开发人员的手动创建&#xff0c;很难保障文档的实时性和有效性。市面上常见的API管理平台&#xff0c;由于缺…

【RabbitMQ实战】04 RabbitMQ的基本概念:Exchange,Queue,Channel等

一、简介 Message Queue的需求由来已久&#xff0c;80年代最早在金融交易中&#xff0c;高盛等公司采用Teknekron公司的产品&#xff0c;当时的Message queuing软件叫做&#xff1a;the information bus&#xff08;TIB&#xff09;。 TIB被电信和通讯公司采用&#xff0c;路透…

Java基础知识

目录 声明 JVM功能说明 功能1&#xff1a;实现Java程序的跨平台性 功能2&#xff1a;自动内存管理(内存分配、内存回收) 相关面试题 关键字和保留字 相关面试题 变量和数据类型 自动类型提升 强制类型转换 基本数据类型转换成字符串 使用String类的valueOf方法&…

怎么把一个音频平均拆分成多个?3个方法快速拆分

怎么把一个音频平均拆分成多个&#xff1f;近年来&#xff0c;随着音频文件在日常生活和工作中的广泛应用&#xff0c;人们对于对音频进行编辑、处理和转换的需求也越来越高。由此&#xff0c;音频编辑软件应运而生&#xff0c;可帮助我们轻松地剪辑、切分、编辑和转换音频文件…

用CRM系统协助销售跟踪客户

客户跟踪对销售来说非常重要&#xff0c;销售不及时跟进很容易导致潜在客户流失。那么对于销售来说&#xff0c;该如何做好客户跟踪呢&#xff1f;或许可以使用CRM客户管理系统。下面来说说&#xff0c;CRM系统如何协助销售跟踪客户&#xff1f; 智能联系客户提醒 销售人员通…

探索视听新纪元: ChatGPT的最新语音和图像功能全解析

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f405;&#x1f43e;猫头虎建议程序员必备技术栈一览表&#x1f4d6;&#xff1a; &#x1f916; 人工智能 AI: &#x1f9e0; Machine …

正则表达式贪婪模式和非贪婪模式

一、贪婪模式 贪婪模式表示尽可能多的匹配字符串&#xff0c;正则表达式六个量词元字符?、、*、{n}、{n,m}、{n,}默认是贪婪模式 接下来引入一个场景来分析说明 获取html a标签href属性的值 <a href"https://www.baidu.com/" attr"abc"></a>…

深度学习与视频直播美颜sdk:背后的技术革新

时下&#xff0c;深度学习技术在视频直播美颜sdk中的应用正引领着一场技术革新的浪潮。本文将探讨深度学习如何在视频直播美颜sdk背后推动了技术的革新&#xff0c;以及它是如何影响我们的日常直播体验的。 一、传统美颜技术的局限性 在深入探讨深度学习之前&#xff0c;让我们…

linux内网渗透

一、信息收集 主机发现&#xff1a; nmap -sP 192.168.16.0/24 端口探测 masscan -p 1-65535 192.168.16.168 --rate1000 开放端口如下 nmap端口详细信息获取 nmap -sC -p 8888,3306,888,21,80 -A 192.168.16.168 -oA ddd4-port目录扫描 gobuster dir…

【EI会议征稿】2023计算机网络技术与电子信息工程国际学术会议(CNTEIE 2023)

2023计算机网络技术与电子信息工程国际学术会议&#xff08;CNTEIE 2023&#xff09; 2023 International Conference on Computer Network Technology and Electronic and Information Engineering 2023计算机网络技术与电子信息工程国际学术会议&#xff08;CNTEIE 2023&a…

Unity中Shader模板测试使用到的二进制

文章目录 前言&#xff08;接上一篇文章&#xff09;一、模板测试公式1、简化版(在ReadMask默认值的情况下)2、完整版 二、二进制的值1、0 和 1组成2、符号3、二进制的与运算4、二进制和十进制转化 三、在Shader中的实际操作 前言&#xff08;接上一篇文章&#xff09; Unity中…

软件测试经验盘点:测试人的至暗时刻高光时刻

作为一名测试工程师&#xff0c;在项目开展中可能会遇到一些困难和挑战&#xff0c;这些情况可能会使我们感到沮丧和无望。以下是一些可能被称为测试工程师的至暗时刻&#xff1a; 项目/版本上线前&#xff1a; ◆需求文档多次评审不通过&#xff0c;浪费了大量的测试时间&…

python 绘制 graphviz

dot 绘图 python 绘制 graphviz 环境 上一节中在本地安装了 graphviz&#xff0c; python 要想使用还需安装 pip 包 pip install graphvizpython 使用 dot Digraph(comment"My Graph") # 添加一些节点 dot.node("A", "Node A") dot.node(&q…