【LeetCode字符串#03】图解翻转字符串中的单词,以及对于for使用的说明
翻转字符串中的单词
给定一个字符串,逐个翻转字符串中的每个单词。
示例 1:
输入: "the sky is blue"
输出: "blue is sky the"
示例 2:
输入: " hello world! "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入: "a good example"
输出: "example good a"
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
思路
以示例1为例,一种或很朴素的想法是:将字符串整个反转
"the sky is blue" ---> "eulb si yks eht"
然后再逐个将单词转回来
那么就有问题了,对于输入格式规范的字符串我们可以想上面那样处理
但是题目所给的输入有可能是不规范的
也就是说,字符串的前面、后间都有可能插入多个空格,反转之后还要将这些空格去除(也就是把格式统一为标准形式)
这就有点难搞
现在大致可以把解题思路分为三部分:
1、将字符串转换为标准形式(去除多余的空格,仅保留单词间的必要空格)
2、将标准字符串整体反转
3、将反转字符串中的单词反转回正常顺序
代码
按照思路来看,都写在主函数里不太现实,可以先把“去除空格”函数和“反转字符串”函数分别写出来
去除空格函数
就根据思路来写
和以前一样,仍需要明确快慢指针的用途
void deleteExtraSpaces(string& s){
//定义慢指针
int slow = 0;
//遍历字符串
for(int fast = 0; fast < s.size(); ++fast){//++i和i++仅在效率上不同
if(s[fast] != ' '){
//如果当前字符(单词)不是第一个字符(单词),那么要在单词前面加空格
if(slow != 0){
s[slow] = ' ';
slow++;
}
//此时找到了单词的开头,需要将其按字符逐个移动到slow所指的位置
//循环条件中需要再判断当前fast是否指向空格,指到就停止移动
//进入下一个for循环,fast指针从道歉位置后移一位
while(fast < s.size() && s[fast] != ' '){
s[slow] = s[fast];
slow++;
fast++;
}
}
}
//因为去除了多余的空格,所以需要重新计算一下数组的大小
s.resize(slow);//此时slow即为标准化后字符串数组的长度
}
上述代码的过程图示如下:

这里 for 有个坑,后面注意事项的时候细说
反转函数
和 反转字符串 里面用的一样,当然也可以用c++提供的
注意:该函数可以反转一条字符串中指定位置的字符
void reverse(string& s, int start, int end){//注意要输入字符串的引用!!!
//在for中同时维护两个变量
for(int i = start, j = end; i < j; i++, j--){
swap(s[i], s[j]);
}
}
完整代码
在主函数里面使用这两个函数完成解题逻辑
class Solution {
public:
void deleteExtraSpaces(string& s){
//定义慢指针
int slow = 0;
//遍历字符串
for(int fast = 0; fast < s.size(); ++fast){//++i和i++仅在效率上不同
if(s[fast] != ' '){
//如果当前字符(单词)不是第一个字符(单词),那么要在单词前面加空格
if(slow != 0){
s[slow] = ' ';
slow++;
}
//此时找到了单词的开头,需要将其按字符逐个移动到slow所指的位置
//循环条件中需要再判断当前fast是否指向空格,指到就停止移动
//进入下一个for循环,fast指针从道歉位置后移一位
while(fast < s.size() && s[fast] != ' '){
s[slow] = s[fast];
slow++;
fast++;
}
}
}
//因为去除了多余的空格,所以需要重新计算一下数组的大小
s.resize(slow);//此时slow即为标准化后字符串数组的长度
}
void reverse(string& s, int start, int end){
//在for中同时维护两个变量
for(int i = start, j = end; i < j; i++, j--){
swap(s[i], s[j]);
}
}
string reverseWords(string s) {
//1、将字符串转换为标准形式,去除空格
deleteExtraSpaces(s);
//2、字符串整体反转
reverse(s, 0, s.size() - 1);//记得减1
//3、恢复每个单词的正常顺序
//依旧使用快慢指针
int slow = 0;//start,fast即为end
for(int fast = 0; fast <= s.size(); ++fast){
if(fast == s.size() || s[fast] == ' '){//到达空格或者字符串结尾倒要反转,不然会漏翻
reverse(s, slow, fast - 1);
slow = fast + 1;//从下一个单词的头开始
}
}
return s;
}
};
正确的思考方式应该是想清楚思路之后,实现每个部分需要的函数,然后再一块搭起来
注意点
1、for循环的特性
本题中大量且灵活的体现了for循环的一些平时容易忽略的特性
循环变量
for(int i = 0; i < xxx; i++){
}
上述是一个典型的for循环结构
要注意的是,开头的这句for(int i = 0; i < xxx; i++)
它只对循环变量 i 进行初始化(赋初值),以及在每次{ }内代码执行完毕后对循环变量执行循环条件(即i++)
至于{ }内发生了什么,for循环本身是不管的。
也就是说,如果我在{ }内对循环变量 i进行了操作,也是允许的
例如:
for(int i = 0; i < xxx; i++){
i = 5;
}//那么下轮循环,i 就从6开始,而不是1
++i和i++
如果你了解前++和后++的区别的话,那你应该知道后++的实现需要借助一个临时变量temp
实际上,在for的日常使用中,使用++i还是i++在结果上是没有区别的
但是如果是刷题的话,++i的执行效率会好一些,仅此而已
2、TBD
【LeetCode字符串#03】图解翻转字符串中的单词,以及对于for使用的说明的更多相关文章
- LeetCode 151:给定一个字符串,逐个翻转字符串中的每个单词 Reverse Words in a String
公众号:爱写bug(ID:icodebugs) 翻转字符串里的单词 Given an input string, reverse the string word by word. 示例 1: 输入: ...
- [LeetCode] Reverse String II 翻转字符串之二
Given a string and an integer k, you need to reverse the first k characters for every 2k characters ...
- 151. Reverse Words in a String翻转一句话中的单词
[抄题]: Given an input string, reverse the string word by word. Example: Input: "the sky is blue& ...
- [LeetCode] 344. Reverse String 翻转字符串
Write a function that reverses a string. The input string is given as an array of characters char[]. ...
- C#版(击败100.00%的提交) - Leetcode 151. 翻转字符串里的单词 - 题解
版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...
- leetcode python翻转字符串里的单词
# Leetcode 151 翻转字符串里的单词### 题目描述给定一个字符串,逐个翻转字符串中的每个单词. **示例1:** 输入: "the sky is blue" 输出: ...
- LeetCode 151 翻转字符串里的单词
题目: 给定一个字符串,逐个翻转字符串中的每个单词. 示例 1: 输入: "the sky is blue" 输出: "blue is sky the" 示例 ...
- LeetCode 翻转字符串里的单词
给定一个字符串,逐个翻转字符串中的每个单词. 示例 1: 输入: "the sky is blue" 输出: "blue is sky the" 示例 2: 输 ...
- 力扣(LeetCode)翻转字符串里的单词 个人题解
给定一个字符串,逐个翻转字符串中的每个单词. 示例 1: 输入: "the sky is blue" 输出: "blue is sky the" 示例 2: 输 ...
- Java实现 LeetCode 151 翻转字符串里的单词
151. 翻转字符串里的单词 给定一个字符串,逐个翻转字符串中的每个单词. 示例 1: 输入: "the sky is blue" 输出: "blue is sky th ...
随机推荐
- docker搭建ddns
ddns 容器 https://hub.docker.com/r/chen... https://github.com/honwen/ali... docker pull chenhw2/aliyun ...
- vue3中使用computed
演示示例(vant组件库的轮播图): <van-swipe :loop="false" :width="150" class="my-Swipe ...
- 【Java并发008】原理层面:ReentrantLock中 await()、signal()/signalAll()全解析
一.前言 上篇的文章中我们介绍了AQS源码中lock方法和unlock方法,这两个方法主要是用来解决并发中互斥的问题,这篇文章我们主要介绍AQS中用来解决线程同步问题的await方法.signal方法 ...
- 图文详解在VMware Workstation 16 PRO虚拟机上安装Rocky 8.6 linux系统
一.安装VMware Workstation虚拟机 下载VMware Workstation 16 PRO虚拟机 https://www.vmware.com/cn/products/workstat ...
- mysql 多个结构不同表查询 返回相同字段名
( select ID,数据库原字段名1 AS 统一字段名1,数据库原字段名2 AS 统一字段名2 from 第一个表名 WHERE 1) UNION(联合表查询)( select ID,数据库原字段 ...
- SpringCloud(十一)- 秒杀 抢购
1.流程图 1.1 数据预热 1.2 抢购 1.3 生成订单 (发送订单消息) 1.4 订单入库 (监听 消费订单消息) 1.5 查看订单状态 1.6 支付 (获取支付链接 ) 1.7 支付成功 微信 ...
- 3 c++编程-提高篇-模版
重新系统学习c++语言,并将学习过程中的知识在这里抄录.总结.沉淀.同时希望对刷到的朋友有所帮助,一起加油哦! 生命就像一朵花,要拼尽全力绽放!死磕自个儿,身心愉悦! 系列文章列表: 1 c+ ...
- 斐波那契散列算法和hashMap实践
斐波那契散列和hashMap实践 适合的场景:抽奖(游戏.轮盘.活动促销等等) 如果有不对的地方,欢迎指正! HashMap实现数据散列: 配置项目,引入pom.xml: <dependency ...
- 我开发的开源项目,让.NET7中的EFCore更轻松地使用强类型Id
在领域驱动设计(DDD)中,有一个非常重要的概念:"强类型Id".使用强类型Id来做标识属性的类型会比用int.Guid等通用类型能带来更多的好处.比如有一个根据根据Id删除用户的 ...
- 【java】【File】用File相关类写一个小工具,完成从指定目录下抽取指定文件并复制到新路径下完成重命名的功能
今日份代码: import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import java.io.*; i ...