【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),因为都只使用了常数级的额外空间。
  • 代码可读性:基于索引的方法代码相对更加简洁,使用索引来处理字符串更加直观,而基于快慢指针的方法需要对指针的操作有较好的理解

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

相关推荐
lmryBC494 分钟前
golang-type关键字
java·数据结构·golang
keep one's resolveY6 分钟前
Tomcat线程池详解,为什么SpringBoot最大支持200并发?
java·开发语言
愚润求学29 分钟前
C++刷题(二):栈 + 队列
开发语言·c++·算法·leetcode
strive-debug43 分钟前
C语言之 循环语句:程序运行的核心动力(上)
算法
无问8171 小时前
SpringBoot配置文件
java·spring boot·后端
爱吃喵的鲤鱼1 小时前
MySQL——数据类型
java·数据库·mysql
子非衣1 小时前
Java解析多层嵌套JSON数组并将数据存入数据库示例
java·数据库·json
..过云雨1 小时前
09.【C++】list链表(STL中的列表容器,C++封装的带头双向链表,可实现指定类型的增删查改,迭代器操作等功能)
开发语言·c++
阿巴~阿巴~1 小时前
C/C++蓝桥杯算法真题打卡(Day6)
c语言·c++·蓝桥杯·动态规划
幼安2291 小时前
日志统计(C++,模拟,双指针)
开发语言·c++·spring