【C++经典例题】反转字符串中单词的字符顺序:两种实现方法详解

💓 博客主页:倔强的石头的CSDN主页****

📝Gitee主页:倔强的石头的gitee主页****

⏩ 文章专栏:C++经典例题

期待您的关注

目录

问题描述

基于快慢指针的解法

基于索引的解法

两种方法的比较


问题描述

在处理字符串相关的问题时,反转字符串中每个单词的字符顺序是一个常见的任务,同时要保证空格和单词的初始顺序不变。

给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。

  • s 包含可打印的 ASCII 字符。
  • s 不包含任何开头或结尾空格。
  • s至少 有一个词。
  • s 中的所有单词都用一个空格隔开。

原题链接:557. 反转字符串中的单词 III - 力扣(LeetCode)

下面我们将详细介绍两种解决该问题的方法,包括其解题思路和具体实现细节。

基于快慢指针的解法

1. 解题思路

快慢指针是一种常用的技巧,在本题中,快指针用于遍历字符串,慢指针用于标记每个单词的起始位置。

当快指针遇到空格时,就表示一个单词已经遍历完,此时可以对慢指针到快指针之间的字符进行反转。

遍历完整个字符串后,还需要对最后一个单词进行反转,因为最后一个单词后面没有空格来触发反转操作。同时,这也对只要一个单词的情况进行了处理

2. 代码实现

cpp 复制代码
class Solution {
public:
    string reverseWords(string s) //快慢指针解法
    {
        string::iterator fast = s.begin();
        string::iterator slow = s.begin();

        while( fast != s.end() )//快指针走完就结束
        {
            if(*fast==' ') //快指针走到空格位置停下,反转该部分字母
            {
                reverse(slow,fast);
                slow = fast+1;
            }
            ++fast;
        }
        reverse(slow,fast);//出循环时,慢指针留在最后一个单词的第一个字母
                           //快指针在\0位置,还需要反转一次
        //同时可以对只要一个单词的string处理
        return s;

    }
};

3. 代码细节分析

  • 指针初始化:首先定义了快指针 fast 和慢指针 slow,并将它们都初始化为字符串 s 的起始位置 s.begin()。
  • **遍历字符串:**通过 while 循环,只要快指针 fast 没有到达字符串末尾 s.end(),就继续循环。
  • 单词反转:当快指针 fast 指向的字符为空格时,说明一个单词已经遍历完,此时调用 reverse 函数将慢指针 slow 到快指针 fast 之间的字符进行反转。然后将慢指针 slow 移动到下一个单词的起始位置,即 fast + 1。
  • **最后一个单词处理:**循环结束后,慢指针 slow 停留在最后一个单词的起始位置,快指针 fast 指向字符串末尾的下一个位置(即 \0 的位置),此时再调用一次 reverse 函数对最后一个单词进行反转。
  • 返回结果:最后返回反转后的字符串 s。

基于索引的解法

1. 解题思路

这种方法使用索引来遍历字符串,通过一个变量记录每个单词的起始位置,当遇到空格或者字符串结束时,对当前单词进行反转。

2. 代码实现

cpp 复制代码
#include <iostream>
#include <string>
#include <algorithm>

class Solution {
public:
    string reverseWords(string s) {
        int start = 0; // 慢指针,标记每个单词的起始位置
        for (int end = 0; end <= s.length(); ++end) {
            // 当遇到空格或者字符串结束时,反转当前单词
            if (end == s.length() || s[end] == ' ') {
                // 反转从 start 到 end - 1 的字符
                std::reverse(s.begin() + start, s.begin() + end);
                // 更新慢指针到下一个单词的起始位置
                start = end + 1;
            }
        }
        return s;
    }
};

3. 代码细节分析

  • **起始位置初始化:**定义变量 start 来记录每个单词的起始位置,初始化为 0。
  • **遍历字符串:**通过 for 循环,使用变量 end 遍历字符串 s,循环条件为 end <= s.length(),这样可以确保在字符串结束时也能处理最后一个单词。
  • **单词反转:**当 end 等于字符串的长度 s.length() 或者 s[end] 为空格时,说明一个单词已经遍历完,此时调用 std::reverse 函数将从 s.begin() + start 到 s.begin() + end 的字符进行反转。
  • **更新起始位置:**反转完当前单词后,将 start 更新为 end + 1,即下一个单词的起始位置。
  • **返回结果:**循环结束后,返回反转后的字符串 s。

两种方法的比较

  • **时间复杂度:**两种方法的时间复杂度都是 O(n),其中 n 是字符串的长度,因为都需要遍历字符串一次,并且每个字符最多被反转一次。
  • **空间复杂度:**两种方法的空间复杂度都是 O(1),因为都只使用了常数级的额外空间。
  • 代码可读性:基于索引的方法代码相对更加简洁,使用索引来处理字符串更加直观,而基于快慢指针的方法需要对指针的操作有较好的理解

通过以上两种方法的详细介绍,我们可以根据具体的需求和个人习惯选择合适的方法来解决反转字符串中单词字符顺序的问题。

相关推荐
极小狐2 小时前
如何使用极狐GitLab 软件包仓库功能托管 maven?
java·运维·数据库·安全·c#·gitlab·maven
容辞2 小时前
算法-贪婪算法
算法·贪心算法
.生产的驴2 小时前
SpringBoot 集成滑块验证码AJ-Captcha行为验证码 Redis分布式 接口限流 防爬虫
java·spring boot·redis·分布式·后端·爬虫·tomcat
Evand J2 小时前
MATLAB程序演示与编程思路,相对导航,四个小车的形式,使用集中式扩展卡尔曼滤波(fullyCN-EKF)
人工智能·算法
野犬寒鸦3 小时前
MySQL索引使用规则详解:从设计到优化的完整指南
java·数据库·后端·sql·mysql
思考的橙子3 小时前
Springboot之会话技术
java·spring boot·后端
椰萝Yerosius4 小时前
[题解]2023CCPC黑龙江省赛 - Ethernet
算法·深度优先
钰爱&4 小时前
【Linux】POSIX 线程信号量与互斥锁▲
java·开发语言·jvm
IT猿手4 小时前
基于 Q-learning 的城市场景无人机三维路径规划算法研究,可以自定义地图,提供完整MATLAB代码
深度学习·算法·matlab·无人机·强化学习·qlearning·无人机路径规划
黑匣子~5 小时前
java集成telegram机器人
java·python·机器人·telegram