翻转字符串中的单词

力扣题目链接(opens new window)

给定一个字符串,逐个翻转字符串中的每个单词。

示例 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
++ii++

如果你了解前++和后++的区别的话,那你应该知道后++的实现需要借助一个临时变量temp

实际上,在for的日常使用中,使用++i还是i++在结果上是没有区别的

但是如果是刷题的话,++i的执行效率会好一些,仅此而已

详见

2、TBD

【LeetCode字符串#03】图解翻转字符串中的单词,以及对于for使用的说明的更多相关文章

  1. LeetCode 151:给定一个字符串,逐个翻转字符串中的每个单词 Reverse Words in a String

    公众号:爱写bug(ID:icodebugs) 翻转字符串里的单词 Given an input string, reverse the string word by word. 示例 1: 输入: ...

  2. [LeetCode] Reverse String II 翻转字符串之二

    Given a string and an integer k, you need to reverse the first k characters for every 2k characters ...

  3. 151. Reverse Words in a String翻转一句话中的单词

    [抄题]: Given an input string, reverse the string word by word. Example: Input: "the sky is blue& ...

  4. [LeetCode] 344. Reverse String 翻转字符串

    Write a function that reverses a string. The input string is given as an array of characters char[]. ...

  5. C#版(击败100.00%的提交) - Leetcode 151. 翻转字符串里的单词 - 题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...

  6. leetcode python翻转字符串里的单词

    # Leetcode 151 翻转字符串里的单词### 题目描述给定一个字符串,逐个翻转字符串中的每个单词. **示例1:** 输入: "the sky is blue" 输出: ...

  7. LeetCode 151 翻转字符串里的单词

    题目: 给定一个字符串,逐个翻转字符串中的每个单词. 示例 1: 输入: "the sky is blue" 输出: "blue is sky the" 示例 ...

  8. LeetCode 翻转字符串里的单词

    给定一个字符串,逐个翻转字符串中的每个单词. 示例 1: 输入: "the sky is blue" 输出: "blue is sky the" 示例 2: 输 ...

  9. 力扣(LeetCode)翻转字符串里的单词 个人题解

    给定一个字符串,逐个翻转字符串中的每个单词. 示例 1: 输入: "the sky is blue" 输出: "blue is sky the" 示例 2: 输 ...

  10. Java实现 LeetCode 151 翻转字符串里的单词

    151. 翻转字符串里的单词 给定一个字符串,逐个翻转字符串中的每个单词. 示例 1: 输入: "the sky is blue" 输出: "blue is sky th ...

随机推荐

  1. 第一百零七篇:基本数据类型(undefined,null,boolean类型)

    好家伙, 本篇内容为<JS高级程序设计>第三章学习笔记 1.数据类型 ECMAScript有6种简单数据类型(称为原始类型): Undefined, Null, Boolean, Numb ...

  2. 【题解】CF1714F Build a Tree and That Is It

    题面传送门 解决思路 题目中虽然说是无根树,但我们可以钦定这棵树的根为节点 \(1\),方便构造,这是不 影响结果的. 以下记给定的三段长度为 \(a,b,c\). 先考虑无解的情况. 首先,给出的三 ...

  3. Go语言核心36讲30

    你好,我是郝林,今天我继续分享条件变量sync.Cond的内容.我们紧接着上一篇的内容进行知识扩展. 问题 1:条件变量的Wait方法做了什么? 在了解了条件变量的使用方式之后,你可能会有这么几个疑问 ...

  4. Kubernetes_k8s持久化存储(亲测可用)

    一.前言 新建具有两个节点的k8s集群,主节点(master节点/m节点)的ip地址是192.168.100.150,从节点(w1节点)的ip地址是192.168.100.151. 本文操作如何将po ...

  5. 说一下 ArrayList 和 LinkedList 的区别?

    本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 前言 大家好,我是小彭. 在上一篇文章里,我们聊到了基于动态数组 ArrayList 线性表,今天我们来讨论 ...

  6. Codeforces Round #835 (Div. 4) A-G

    比赛链接 A 题意 给出三个不同的数,求中位数. 题解 知识点:模拟. 显然. 时间复杂度 \(O(1)\) 空间复杂度 \(O(1)\) 代码 #include <bits/stdc++.h& ...

  7. 启动homestead虚拟机 vagrant up执行后,提示Timed out while waiting for the machine to boot

    最近在启动homestead虚拟机时,总会卡在ssh验证这,几分钟后,就报timed out-- 以往都是重启电脑后,再次执行vagrant up后就能正常启动. 今日重启电脑很多次也无用. 查询解决 ...

  8. PGL图学习之项目实践(UniMP算法实现论文节点分类、新冠疫苗项目实战,助力疫情)[系列九]

    原项目链接:https://aistudio.baidu.com/aistudio/projectdetail/5100049?contributionType=1 1.图学习技术与应用 图是一个复杂 ...

  9. 猿人学web爬虫攻防大战

    这里有1.2.3.4.12.13.15题 1.第一题 import execjs import requests def get_response(): js_code = ""& ...

  10. python什么是异常?如何处理异常

    异常处理 什么是异常 异常是程序错误发生的信号.程序一旦出现错误,就会产生一个异常,如果程序中没有处理该异常,该异常就会抛出来,程序的运行也随即终止. 错误分为两种 1.语法错误 2.逻辑错误 如何处 ...