当前位置: 首页 > news >正文

LeetCode 151. 反转字符串中的单词

LeetCode 151. 反转字符串中的单词 解析

这个问题要求将给定字符串中的单词顺序反转,同时移除多余空格,使得每个单词之间只有一个空格,且字符串首尾无空格。

方法思路

最优解法是原地反转法:通过三次反转操作实现单词顺序的反转,同时处理多余空格。具体步骤如下:

  1. 移除多余空格
    将字符串中的多余空格去除,只保留单词间的单个空格,并调整字符串长度。

  2. 整体反转
    将处理后的字符串整体反转。

  3. 单词反转
    遍历字符串,对每个单词进行局部反转,恢复单词的原始顺序。

C++ 代码实现

#include <string>
#include <algorithm>class Solution {
public:string reverseWords(string s) {// 1. 移除多余空格int i = 0, j = 0;  // i 为写入指针,j 为读取指针while (j < s.length()) {// 跳过前导空格while (j < s.length() && s[j] == ' ') j++;if (j >= s.length()) break;  // 处理全空格的情况// 添加单词和中间空格if (i != 0) s[i++] = ' ';  // 单词间添加一个空格while (j < s.length() && s[j] != ' ') {s[i++] = s[j++];}}s.resize(i);  // 调整字符串长度// 2. 整体反转reverse(s.begin(), s.end());// 3. 逐个单词反转i = 0;for (int j = 0; j <= s.length(); j++) {if (j == s.length() || s[j] == ' ') {  // 遇到空格或字符串末尾reverse(s.begin() + i, s.begin() + j);i = j + 1;  // 更新下一个单词的起始位置}}return s;}
};

代码解释

  1. 移除多余空格

    • 使用双指针 ij,其中 j 用于遍历原字符串,i 用于写入处理后的字符。
    • 跳过前导空格,遇到单词时将其复制到 i 位置,并在单词间添加单个空格。
    • 最终使用 resize(i) 调整字符串长度,去除尾部冗余字符。
  2. 整体反转
    使用 reverse(s.begin(), s.end()) 将整个字符串反转,此时单词顺序已反转,但每个单词内部字符顺序也被反转。

  3. 单词反转

    • 遍历字符串,每当遇到空格或字符串末尾时,将当前单词(从 ij-1)进行局部反转。
    • 更新 i 为下一个单词的起始位置(j+1)。

复杂度分析

  • 时间复杂度:O(n),其中 n 是字符串的长度。每个字符最多被处理三次(移除空格、整体反转、单词反转)。
  • 空间复杂度:O(1),仅需常数级的额外空间。

示例

输入:s = " hello world! "
输出:"world! hello"
解释

  1. 移除多余空格"hello world!"
  2. 整体反转"!dlrow olleh"
  3. 单词反转"world! hello"

关键点

  1. 原地修改
    通过双指针法在原字符串上直接操作,避免额外空间开销。

  2. 三次反转策略
    整体反转+单词反转的组合巧妙地实现了单词顺序的反转,同时保持单词内容正确。

  3. 边界处理

    • 处理字符串首尾的多余空格。
    • 处理连续多个空格的情况。
    • 处理空字符串或全空格字符串的情况。

这种方法高效且符合题目要求,是解决此类问题的经典思路。

方法二:

class Solution {
public:string reverseWords(string s) {stringstream ss(s);vector<string> words;string word;while (ss >> word){words.emplace_back(word);}string res = words[words.size() - 1];for (int i = words.size() - 2; i >= 0; --i){res += " ";res += words[i];}return res;}
};
http://www.dtcms.com/a/269121.html

相关文章:

  • 软考(软件设计师)存储管理—存储空间管理,文件共享保护
  • 虚幻引擎Gameplay框架
  • STM32固件升级设计——串口IAP升级(基于YMODEM协议)
  • CosyVoice2.0整合包:免费一键启动,释放语音克隆的创意潜能
  • day048-系统负载高排查流程与前后端分离项目
  • 上传Vue3+vite+Ts组件到npm官方库保姆级教程
  • python高级变量XIV
  • 【数据结构之哈夫曼树与编码实现】
  • 【Linux操作系统】简学深悟启示录:Linux基本指令
  • OpenStack扩展
  • 05. study_JSBridge机制
  • 7.7日 实验03-Spark批处理开发(2)
  • Playfun即将开启大型Web3线上活动,打造沉浸式GameFi体验生态
  • C++11标准库算法:深入理解std::none_of
  • 低代码平台的性能测试实践与挑战
  • qiankun 微前端项目中的 Token 鉴权方案
  • python dict list 去重
  • 【数据驱动视角下的流体模拟:CFD 与深度学习(GANs/PINN)在圆柱绕流及机翼分析中的应用】
  • Video Background Remover V3版 - AI视频一键抠像/视频换背景 支持50系显卡 一键整合包下载
  • 动手学深度学习13.7. 单发多框检测(SSD)-笔记练习(PyTorch)
  • Pycharm恢复默认设置,配置导致复制粘贴等不能使用
  • 气候大模型的演化路径与产业落地展望:AI重构全球气候科学的新范式
  • 在bash shell 函数传递数组的问题
  • CSS知识复习4
  • 卷积神经网络:卷积层的核心原理与机制
  • MATLAB | 绘图复刻(二十一)| 扇形热图+小提琴图
  • C++11中的std::ratio:编译时有理数运算的艺术
  • 暑假算法日记第三天
  • WebRTC与RTMP
  • iOS App抓包工具排查后台唤醒引发请求异常