算法力扣刷题记录 二十三【151.翻转字符串里的单词】

前言

字符串篇,继续。
记录 二十三【151.翻转字符串里的单词】

一、题目阅读

给你一个字符串 s ,请你反转字符串中 单词 的顺序。

单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。

返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。

注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

示例 1:

输入:s = "the sky is blue"
输出:"blue is sky the"

示例 2:

输入:s = "  hello world  "
输出:"world hello"
解释:反转后的字符串中不能存在前导空格和尾随空格。

示例 3:

输入:s = "a good   example"
输出:"example good a"
解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。

提示:

1 <= s.length <= 104
s 包含英文大小写字母、数字和空格 ' '
s 中 至少存在一个 单词

进阶:

如果字符串在你使用的编程语言中是一种可变数据类型,请尝试使用 O(1) 额外空间复杂度的 *原地* 解法。

二、尝试实现

思路

(1)对参数s应该以空格为分隔符,分割一个一个单词。
(2)流对象能够忽略空格或‘\n’,虽然读取,但是能够忽略。

用stringstream可以完成以空格分割和忽略读取到的空格。

代码实现(测试通过)

class Solution {
public:string reverseWords(string s) {string result;	//返回值stringstream ss(s);	//处理字符串的流对象定义。string str;while(ss>>str){	//用>>运算符可以忽略空格,以空格为分隔符if(result.empty()){result.insert(0,str);}else{result.insert(0,str+' ');	//在新string}  }return result;}
};

进阶

在原有字符串中进行解决:

进阶思路

结合记录二十二的思路,在原有string s的后面扩容,把新倒序的单词续到原有字符串的后面。最后再把前面size长度删掉,只取size之后的。

思路示意

(1)首先不能覆盖填充,因为单词不能改变,所以覆盖填充会改变原有的单词。所以就把倒序操作放到整个size的后面
(2)扩容多大区间?

  • 统计多少个字母;假设count个字母;
  • 统计一共多少个单词。假设有n个单词,需要n-1个空格。
  • 所以扩容count+n-1。在原有size的后面。
  • 总结:s.resize(size+count+n-1);

(3)接下来,翻转单词顺序。

  • 一个指针i从s[size-1]倒着往前找单词,直到s[i] != ’ '。i不再是空格;
  • 单词内的字母没有倒序,所以得找这个单词的头。用指针j=i-1开始,往前找,直到s[j] == ’ '等于空格。s[j+1]~s[i]之间是一个单词。
  • 用一个指针k记录扩容后面的位置,要把“s[j+1]~s[i]”这个单词放在哪个位置?k初始是size。从s[size]开始。
  • 空格处理:
    • 如果是倒数第一个单词,那么前面不需要有空格;如果不是倒数第一个单词,就要有空格。

代码实现(测试通过)

可以查看注释解释

class Solution {
public:string reverseWords(string s) {int size = s.size();int count = 0;  //统计有多少个字母int num = 0;    //统计多少个单词for(int i = 0;i < size;i++){  if(s[i] != ' '){	//挨个遍历原来的size,不是空格时,count可以++count++;if(i+1 < size && s[i+1]==' ' ){	//如果下一位是空格,说明是一个单词,所以num++num++;}else if(i == size-1){	//如果s[size-1]不是空格,最后一个单词也要加上。num++;}}}s.resize(size+count+num-1);//扩容//在扩容的区间开始翻转单词顺序int k = size;int phase = 0;//倒着往前找for(int i =size-1;i >=0;){if(s[i] != ' '){	//遇到一个单词的末尾字母int j = i-1;int subchar = 1;phase++;		//记录当前翻转的第几个单词for(j;j >=0;j--){	//找这个单词多长,for结束后s[j+1]是这个单词的首字母if(s[j] == ' '){break;}subchar++;	//记录单词多长}if(phase != 1){	//如果不是倒数第一个单词,在后面放单词之前先加一个空格。s[k++] = ' ';}for(int m = 0;m < subchar;m++){	//单词字母没有倒转,所以正向的顺序把字母放置好。s[k++] = s[j+m+1];}i = j;}i--;}s.erase(0,size);	//最后删除从0开始,长度为size的部分。把原有部分删除。return s;}
};

总结:两种方法都解决了。这种扩容可以认为是原地操作。


三、代码随想录学习

学习内容

主要看思路区别和实现区别:
(1)用split库函数,分割string s , 再用一个新字符串。C++里面没有split的函数。要么就是C风格的strtok函数,在< cstring >中,原来的string.h。
(2)因为想到reverse翻转会直接把字母翻转,就没再考虑;其实可以reverse整个string s,再把每个单词reverse回来。
(3)处理空格:多余的空格要删掉,如果不是第一个单词,前面还要留一个空格。(删除空格,也是删除元素,string可以像数组一样操作,所以用双指针法)

代码实现

class Solution {
public:
void phaseReverse(string& s,int start ,int end){	//库函数reverse使用类型iterator。if(start > s.size() || end < 0){return;}for(int i = start,j = end-1;i < j;i++,j--){ //左闭右开swap(s[i] ,s[j]);}}string reverseWords(string s) {//删除空格int fast = 0;int slow = 0;for(;fast < s.size();fast++){if(s[fast] != ' '){		//当遇到不该删的字符。如果没有这个判断,单词之间的空格没有删掉。if( slow != 0){s[slow++] = ' ';//先给空格再slow++}while(fast < s.size() && s[fast] != ' '){	//必须有 < s.size() 判断,没有会越界。s[slow] = s[fast];fast++;slow++;}}}s.resize(slow);reverse(s.begin(),s.end());//在翻转每个单词for(int i = 0,j = 0;j <= s.size();j++){	//因为phaseReverse左闭右开,所以j <= ,带等号。if(s[j] == ' ' || j == s.size()){phaseReverse(s,i,j);i = j+1;}}return s;}
};

总结

(1)用一个新string,用stringstream处理。
(2)扩容原来的string s,倒着往前找单词,放到后面,最后把前面长size的内容erase。
(3)先删除空格(双指针法),再reverse整体,再翻转某个单词。

(欢迎指正,转载表明出处)

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

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

相关文章

【04】从0到1构建AI生成思维导图应用 -- 创建 AI 工作流

【04】从0到1构建AI生成思维导图应用 – 创建 AI 工作流 大家好&#xff01;最近自己做了一个完全免费的AI生成思维导图的网站&#xff0c;支持下载&#xff0c;编辑和对接微信公众号&#xff0c;可以在这里体验&#xff1a;https://lt2mind.zeabur.app/ 上一章&#xff1a;h…

centos7安装mysql8-zabbix6.4

MySQL rpm -qa | grep mysql #查看是否已经安装 Mysql rpm -qa | grep mariadb #查看是否已经安装 mariadb,CentOS 7可视化安装会默认安装该数据库,安装MySQL前需要卸载该数据库 rpm -e --nodeps mariadb-libs #删除mariadb数据库找到对应linux的版本进行下载 […

从零开始:Spring Boot 中使用 Drools 规则引擎的完整指南

规则引擎作用 规则引擎主要用于将业务逻辑从应用程序代码中分离出来&#xff0c;提高系统的灵活性和可维护性。规则引擎通过预定义的规则来处理输入数据并做出相应的决策&#xff0c;从而实现业务逻辑的自动化和动态调整。 例如 门店信息校验&#xff1a;美团点评在门店信息…

【高中数学之基本不等式】已知:a,b皆为正实数且1/a+1/(b+2)=1/2 求:a+b的最小值?

解&#xff1a;先从1/a1/(b2)1/2 入手&#xff0c;看能否化二为一&#xff08;将两变量化成一个变量&#xff09; 由1/a1/(b2)1/2 两边通分得(b2a)/a/(b2)1/2 交叉相乘得2a2b4ab2a 最后得到a24/b 所以ab24/bb 此时已经可以用基本不等式了 ab24/bb>22*根号下(4/b*b)22…

SpringBoot 3.3.1 + Minio 实现极速上传和预览模式

统一版本管理 <properties><minio.version>8.5.10</minio.version><aws.version>1.12.737</aws.version><hutool.version>5.8.28</hutool.version> </properties><!--minio --> <dependency><groupId>io.m…

Arduino - TM1637 4 位 7 段显示器

Arduino - TM1637 4 位 7 段显示器 Arduino-TM1637 4 位 7 段显示器 A standard 4-digit 7-segment display is needed for clock, timer and counter projects, but it usually requires 12 connections. The TM1637 module makes it easier by only requiring 4 connectio…

有哪些防爬虫的方法

防爬虫的方法有robots.txt文、user-agent过滤、ip限制、验证码、动态页面生成、频率限制、动态url参数和反爬虫技术等。详细介绍&#xff1a;1、robots.txt文件&#xff0c;用于告诉搜索引擎爬虫哪些页面可以访问&#xff0c;哪些页面禁止访问&#xff1b;2、ip限制&#xff0c…

关于vs code中Live Server插件安装后无法打开的问题

一、问题情况 安装好Live Server插件之后&#xff0c;点击open with live server只会出现界面右下角落的提示&#xff0c;但是不会跳转到浏览器的页面&#xff1a;如下所示&#xff1a; 二&#xff1a;解决步骤 1、首先进行扩展设置&#xff0c;默认将浏览器的设置为chrome浏览…

vue组件全局注册

描述&#xff1a; vue组件的注册分为局部和全局注册两部分&#xff0c;局部注册相对容易&#xff0c;不做赘述&#xff1b;而不同框架的注册方法又有所不同&#xff0c;下面针对vite框架和vue-cli框架的注册分别进行说明 vue组件全局注册 一、vite框架中全局组件注册二、Vue-cl…

-bash: /snap/bin/docker: 没有那个文件或目录

-bash: /snap/bin/docker: 没有那个文件或目录 解决办法 export PATH$PATH:/usr/bin/docker然后&#xff0c;重新加载配置文件 source ~/.bashrc

线程的等待通知机制

等待通知机制 之前所学到的join是等待线程结束,而此时的等待通知,等待代码给我们提示进行显示的通知(并不一定要结束),可以更加精细控制线程之间的执行顺序,在系统内部,线程是抢占式执行,随机调度,但是程序员也是有手段可以进行干预的,我们可以通过"等待"的方式让线…

【学术日记】关于读博,目标院校,意向导师,毕业要求,重要时间点

文章目录 一、目标院校二、重要时间点西安交通大学意向导师 华南理工大学意向导师 本文记录博主的科研日记。如果对博主的其他文章感兴趣&#xff0c;可以看这篇文章【CSDN文章】晚安66博客文章索引。 首次修改时间&#xff1a;2024年5月12日。当前修改时间&#xff1a;2024年5…

C : 线性规划例题求解

Submit Page TestData Time Limit: 1 Sec Memory Limit: 128 Mb Submitted: 93 Solved: 49 Description 求解下述线性规划模型的最优值min &#xfffd;1&#xfffd;1&#xfffd;2&#xfffd;2&#xfffd;3&#xfffd;3&#xfffd;.&#xfffd;. &…

Spring Cloud LoadBalancer基础入门与应用实践

官网地址&#xff1a;https://docs.spring.io/spring-cloud-commons/reference/spring-cloud-commons/loadbalancer.html 【1】概述 Spring Cloud LoadBalancer是由SpringCloud官方提供的一个开源的、简单易用的客户端负载均衡器&#xff0c;它包含在SpringCloud-commons中用…

前端vue使用onlyoffice控件实现word在线编辑、预览(仅列出前端部分需要做的工作,不包含后端部分)

简介 ONLYOFFICE 文档 是一个开源办公套件&#xff0c;包括文本文档、电子表格、演示文稿和可填写表单的编辑器。 它提供以下功能&#xff1a; 创建、编辑和查看文本文档、电子表格、演示文稿和可填写表单&#xff1b; 与其他队友实时协作处理文件。 基于这个控件&#xff0c;…

基于Java毕业生生活用品出售网站的设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;…

【算能全国产AI盒子】基于BM1688CV186AH+FPGA智能物联工作站,支持差异化泛AI视觉产品定制

在数据呈现指数级增长的今天&#xff0c;越来越多的领域和细分场景对实时、高效的数据处理和分析的需求日益增长&#xff0c;对智能算力的需求也不断增强。为应对新的市场趋势&#xff0c;凭借自身的硬件研发优势&#xff0c;携手算能相继推出了基于BM1684的边缘计算盒子&#…

MySQL3(多表联查 子查询 流程控制函数,语句 Sql 执行顺序 学生选课表练习)

目录 一、多表联查 1. 等值查询和非等值查询 等值查询 --- 主外键相等 ​编辑非等值查询 2. 连接查询 ​编辑 内连接 ​编辑 左外连接 ​编辑 右外连接 3. UNION 二、子查询 1. where 型子查询&#xff1a; 2. from型子查询: 3. exists型子查询: 4. any, some…

笔记本重装系统怎么操作? windows电脑重装系统,超实用的四种方法

重新安装操作系统是维护计算机性能和确保系统稳定运行的重要步骤。对于 Windows 笔记本用户而言&#xff0c;熟悉重装系统的方法可以帮助他们解决各种问题&#xff0c;从提高系统速度到修复软件故障。然而具体来讲&#xff0c;笔记本重装系统怎么操作呢&#xff1f;接下来&…

LLDP 基本原理

LLDP 简介 定义 LLDP&#xff08;Link Layer Discovery Protocol&#xff0c;链路层发现协议&#xff09;是 IEEE 802.1ab 中定义的第二层发现&#xff08;Layer 2 Discovery&#xff09;协议。 LLDP 提供了一种标准的链路层发现方式&#xff0c;可以将本端设备的主要能力、…