力扣151题——翻转字符串中单词C++讲解

目录

一.题目描述

二.题目示例

三.解题分析

四. 代码讲解

 五.知识点总结

   


来源:力扣(LeetCode
链接:https://leetcode-cn.com/problems/reverse-words-in-a-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

一.题目描述

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

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

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

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

二.题目示例

示例一:

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

示例二:

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

示例三:

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

三.解题分析

本题采用先反转全部字符串,再把单词逐一反转回来的解法

      首先,我们需要把全部字符串翻转过来,这时候就需要用到一个reverse函数。

      然后 ,我们就需要遍历整个字符串,在其中寻找单词,把单词反转过来。所以就必须精确的寻找到单词的起始位置和结束位置,这里我们需要用到两个指针,可以定义为start(代表该单词的起始位置)和end(代表该单词的结束位置),当两个指针位置确定好时就可以将该单词反转过来,但是重要的是字符串反转了,指针指向的位置确实不变的,end指针还是指向该单词的末尾,想要继续寻找下一个单词,则start=end。 这时候还需要一个变量target来确定所记录过的所有单词的字母个数s[target++]=s[end++];若target!=0,则证明不是第一个单词,在两个单词之间添加空格。(字符串修改是在原字符串上改的,所以跳过的字符相当于没有,所以需要加也只能加一个空格)

反转单词的start和end怎么确定呢?

       start为该单词起始位置,相对于s字符串来说为s.begin()+target-(end-start)//所记录的所有长度-该单词长度

       end为该单词结束位置,先对于s字符串来说为s.begin()+target//所记录所有单词长度

       最后,需要用到erase函数删除最后面的几个空格 。

  • 时间复杂度:O(n),其中 n为输入字符串的长度。

基本步骤:

1.翻转字符串

2.遍历字符串寻找不是空格的字符

3.确定end指针和target位置

4.翻转字符串,再跳过该单词寻找下一个单词

4.删除字符串多余字符,输出字符串

以下为字符串翻转示例 

 

 

四. 代码讲解

万事俱备,只欠东风!让我为大家讲解(注:仅为讲解代码,帮助家人们理解)一下代码吧!

class Solution {
public:
    string reverseWords(string s) {
        reverse(s.begin(),s.end());//翻转字符串
        int n=s.size();
        //定义target记录所记录过的所有单词的字母个数,也用来向单词之间添加空格
        int target=0;
        for(int start=0;start<n;start++){//遍历字符串
            if(s[start]!=' '){
                if(target!=0)s[target++]=' ';//若不是第一个单词,则在两个单词中间添加空格

                int end=start;//定义end指针
                while(end<n&&s[end]!=' ')s[target++]=s[end++];//确定end指针位置
                //翻转所找到的单词
                reverse(s.begin()+target-(end-start),s.begin()+target);
                start=end;//重新定义start位置,寻找新单词

            }
        }
        s.erase(s.begin()+target,s.end());//删除多余字符
        return s;
    }
};

 五.知识点总结

reverse函数用于反转在[first,last)范围内的顺序(包括first指向的元素,不包括last指向的元素),reverse函数没有返回值

例:这题我们就可以写为reverse(s.begin(),s.end()); 

erase函数三种用法:

erase(begin, n):删除从begin开始的n个字符
erase(position):删除position处的字符,例position=3为删除下标为3的字符
erase(begin, end):删除从begin到end之间的字符(包括begin,不包括end)

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值