【字符串】——翻转字符串中的单词

news2024/11/6 17:24:37

151. 反转字符串中的单词

题目难度

中等

题目描述

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

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

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

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

示例

示例 1

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

示例 2

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

示例 3

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

提示信息

  • 1 <= s.length <= 104
  • s包含英文大小写字母、数字和空格 ' '
  • s中至少存在一个单词。

解题思路

  1. 去除多余空格

    • 首先,去除输入字符串s中的前导空格、尾随空格以及单词之间的多余空格。可以通过遍历字符串,使用一个新的字符串来存储处理后的结果。当遇到非空格字符时,将其添加到新字符串中;当遇到空格且新字符串不为空时,再添加一个空格。这样可以确保新字符串中单词之间只有一个空格。
  2. 反转整个字符串

    • 对去除多余空格后的字符串进行反转。可以使用双指针的方法,一个指针从字符串的开头开始,另一个指针从字符串的末尾开始,不断交换两个指针所指的字符,直到两个指针相遇。
  3. 反转每个单词

    • 再次遍历反转后的字符串,确定每个单词的边界。当遇到空格时,说明一个单词结束,可以对这个单词进行反转。同样可以使用双指针的方法,一个指针指向单词的开头,另一个指针指向单词的末尾,不断交换两个指针所指的字符,直到两个指针相遇。

解法一:反转两次

  • 先删除空白
  • 整个反转
  • 单词反转,转回来了
class Solution:
    def reverseWords(self, s: str) -> str:
        # 删除前后空白
        s = s.strip()
        # 反转整个字符串
        s = s[::-1]
        # 将字符串拆分成单词,并且反转每个单词
        s = ' '.join(word[::-1] for word in s.split())
        return s
  • 因为字符串在python时是不可变类型,所以反转单词时,需要先将其转换成列表,然后通过join函数再将其转换成列表,所以空间复杂度不是 O ( 1 ) O(1) O(1)

解法二:双指针反转

class Solution:
    def reverseWords(self, s: str) -> str:
        # 将字符串char拆分成单词 '' ,即转换成列表类型
        # s = '  hello    world  '
        words = s.split()  # words = ['hello','world']
        # 双指针反转单词'位置'
        left, right = 0, len(words) - 1
        while left < right:
            words[left], words[right] = words[right], words[left]
            left += 1
            right -= 1
        
        # words = ['world','hello']
        return ' '.join(words)       

解法三:拆分字符串+反转列表

class Solution:
    def reverseWords(self, s):
        words = s.split()  # char ---> list = ['','','']
        words = words[::-1] # 切片快速反转单词位置
        return ' '.join(words)
         

以下是对三种解法的详细分析:

解法一:反转两次

  1. 思路

    • 首先使用strip()方法去除字符串前后的空白。
    • 然后通过切片操作s[::-1]反转整个字符串。
    • 最后,使用列表推导式将字符串按空格分割成单词列表,对每个单词进行反转,再用join方法将反转后的单词重新组合成字符串。
  2. 优点

    • 代码较为简洁,利用了 Python 的内置函数和切片操作,容易理解。
  3. 缺点

    • 正如你所说,由于字符串在 Python 中是不可变类型,在反转单词时需要将字符串转换为列表再转换回字符串,这会带来一定的开销,并且空间复杂度不是 O ( 1 ) O(1) O(1)
  4. 时间复杂度

    • strip()的时间复杂度为 O ( n ) O(n) O(n),其中 n 是字符串的长度。
    • 切片操作s[::-1]的时间复杂度为 O ( n ) O(n) O(n)
    • 分割字符串和对每个单词进行反转的时间复杂度也为 O ( n ) O(n) O(n),因为涉及遍历整个字符串。所以总体时间复杂度为 O ( n ) O(n) O(n)
  5. 空间复杂度

    • 由于需要创建新的列表来存储反转后的单词,所以空间复杂度不是 O ( 1 ) O(1) O(1),具体取决于字符串中的单词数量和长度。

解法二:双指针反转

  1. 思路

    • 首先使用split()方法将字符串拆分成单词列表。
    • 然后使用双指针的方法交换单词列表中单词的位置,实现单词顺序的反转。
    • 最后,使用join方法将反转后的单词列表重新组合成字符串。
  2. 优点

    • 不需要对每个单词进行单独的反转操作,只需要进行一次双指针反转单词位置的操作,相对高效。
    • 没有创建额外的数据结构来存储反转后的单词,空间复杂度相对较低。
  3. 缺点

    • 代码相对解法一稍微复杂一些,需要理解双指针的操作。
  4. 时间复杂度

    • split()方法的时间复杂度为 O ( n ) O(n) O(n),其中 n 是字符串的长度。
    • 双指针反转单词位置的操作时间复杂度为 O ( m ) O(m) O(m),其中 m 是单词的数量。由于单词数量通常小于字符串长度,所以总体时间复杂度为 O ( n ) O(n) O(n)
  5. 空间复杂度

    • 只创建了一个单词列表,没有创建其他额外的数据结构,空间复杂度取决于单词的数量和长度,相对较低,可以认为接近 O ( m ) O(m) O(m),其中 m 是单词的数量。

解法三:拆分字符串 + 反转列表

  1. 思路

    • 与解法二类似,首先使用split()方法将字符串拆分成单词列表。
    • 然后直接使用切片操作words[::-1]反转单词列表。
    • 最后,使用join方法将反转后的单词列表重新组合成字符串。
  2. 优点

    • 代码简洁,利用了切片操作快速反转单词列表。
  3. 缺点

    • 与解法一类似,需要将字符串拆分成单词列表,可能会带来一定的开销。并且空间复杂度不是 O ( 1 ) O(1) O(1)
  4. 时间复杂度

    • split()方法的时间复杂度为 O ( n ) O(n) O(n),其中 n 是字符串的长度。
    • 切片操作words[::-1]的时间复杂度为 O ( m ) O(m) O(m),其中 m 是单词的数量。总体时间复杂度为 O ( n ) O(n) O(n)
  5. 空间复杂度

    • 创建了一个单词列表,空间复杂度取决于单词的数量和长度,不是 O ( 1 ) O(1) O(1)

综上所述,三种解法的时间复杂度都是 O ( n ) O(n) O(n),但解法二在空间复杂度上相对较低,并且代码也较为高效。解法一和解法三虽然代码简洁,但在空间复杂度上有一定的不足。在实际应用中,可以根据具体情况选择合适的解法。

切片操作是只能对列表进行么?

切片操作words[::-1]的时间复杂度为 O ( m ) O(m) O(m),其中 m m m 是切片操作所作用的序列的长度,在这个例子中就是单词列表words中单词的数量。

切片操作不仅可以对列表进行,也可以对字符串这种数据类型进行。对于字符串的切片操作,其语法和对列表的切片操作类似,例如:

s = "hello world"
print(s[::-1])  
print(s[1:5])  

在上述代码中,s[::-1]会将字符串s反转,得到dlrow ollehs[1:5]会截取字符串s中从索引为1的字符到索引为4的字符,得到ello

字符串切片操作的时间复杂度也是与切片的长度相关的,对于长度为 n n n 的字符串,切片操作的时间复杂度通常为 O ( k ) O(k) O(k),其中 k k k 是切片的长度,也就是切片操作所选取的字符数量。在最坏的情况下,如果切片选取了整个字符串,时间复杂度就是 O ( n ) O(n) O(n)

所以,切片操作是一种非常方便且高效的操作,可以用于多种序列类型的数据,包括列表、字符串、元组等,能够帮助我们灵活地获取和处理序列中的部分数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2234410.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MySQL初阶】--- MySQL在Ubuntu环境下安装

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; MySQL 本篇博客博主采用的是ubuntu 22.04的系统按照MySQL&#xff0c;且在root用户下安装。 &#x1f3e0; MySQL安装 1. 更新系统的软件包列表 sudo a…

Charles简单压力测试

1.接口请求次数&#xff0c;并发量&#xff0c;请求延迟时间均可配置 1.1选中需要进行测试的接口&#xff0c;鼠标右键选中【repeat advance】 2.设置并发参数 下面的图中&#xff0c;选择了1个接口&#xff0c;每次迭代中1个接口同时请求&#xff0c;迭代1000次&#xff08;…

【大模型LLM面试合集】大语言模型架构_chatglm系列模型

chatglm系列模型 1.ChatGLM 1.1 背景 主流的预训练框架主要有三种&#xff1a; autoregressive自回归模型&#xff08;AR模型&#xff09;&#xff1a;代表作GPT。本质上是一个left-to-right的语言模型。通常用于生成式任务&#xff0c;在长文本生成方面取得了巨大的成功&a…

从 vue 源码看问题 — 你知道 Hook Event 吗?

前言 在之前的几篇文章中&#xff0c;都有提到 vue 中调用生命周期钩子时是通过 callHook() 方法进行调用的&#xff0c;比如在初始化篇章中调用 beforeCreate 和 created 生命周期钩子方式如下: 那么接下来一起来了解下到底什么是 Hook Event &#xff1f; Hook Event 是什…

html练习2

实现下列图片的效果 代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>* {margin: 0;padding: 0;}#menu {background-color: #0c0048;width: 100%;height: 50px;margin: auto;…

计算机视觉常用数据集Cityscapes的介绍、下载、转为YOLO格式进行训练

我在寻找Cityscapes数据集的时候花了一番功夫&#xff0c;因为官网下载需要用公司或学校邮箱邮箱注册账号&#xff0c;等待审核通过后才能进行下载数据集。并且一开始我也并不了解Cityscapes的格式和内容是什么样的&#xff0c;现在我弄明白后写下这篇文章&#xff0c;用于记录…

Java | Leetcode Java题解之第523题连续的子数组和

题目&#xff1a; 题解&#xff1a; class Solution {public boolean checkSubarraySum(int[] nums, int k) {int m nums.length;if (m < 2) {return false;}Map<Integer, Integer> map new HashMap<Integer, Integer>();map.put(0, -1);int remainder 0;fo…

MATLAB计算朗格朗日函数

1. 朗格朗日函数介绍 朗格朗日函数&#xff08;Lagrange function&#xff09;通常用于优化问题&#xff0c;尤其是带有约束的优化问题。其一般形式为&#xff1a; 其中&#xff1a; f(x) 是目标函数。 是约束条件。 是拉格朗日乘子。 为了编写一个MATLAB代码来计算和绘制…

手机的ip地址是固定的吗?多角度深入探讨

手机的IP地址是否固定&#xff0c;这一问题涉及到网络连接、技术配置以及运营商策略等多个方面。为了全面解答这一问题&#xff0c;我们需要从多个角度进行深入探讨。 首先&#xff0c;明确IP地址&#xff08;Internet Protocol Address&#xff09;的基本概念。IP地址是互联网…

宠物空气净化器推荐,哪款除毛好、噪音小?希喂、352性能对比

大家都有选购宠物空气净化器时在各大品牌里挑挑拣拣、费时费力的体验吧...本以为只要多看点推荐&#xff0c;确定了品牌&#xff0c;就能买到好用的产品&#xff0c;不过实际情况却并非如此。 身为宠物博主&#xff0c;之前用过不少宠物空气净化器&#xff0c;20年还写过几篇测…

`掌握Python-PPTX,让PPt制作变得轻而易举!`

文章目录 掌握Python-PPTX&#xff0c;让PPT制作变得轻而易举&#xff01;背景介绍python-pptx 是什么&#xff1f;如何安装 python-pptx&#xff1f;简单库函数使用方法应用场景常见Bug及解决方案总结 掌握Python-PPTX&#xff0c;让PPT制作变得轻而易举&#xff01; 背景介绍…

【python】OpenCV—Connected Components

文章目录 1、任务描述2、代码实现3、完整代码4、结果展示5、涉及到的库函数6、参考 1、任务描述 基于 python opencv 的连通分量标记和分析函数&#xff0c;分割车牌中的数字、号码、分隔符 cv2.connectedComponentscv2.connectedComponentsWithStatscv2.connectedComponents…

ENSP (虚拟路由冗余协议)VRRP配置

VRRP&#xff08;Virtual Router Redundancy Protocol&#xff0c;虚拟路由冗余协议&#xff09;是一种用于提高网络可用性和可靠性的协议。它通过在多个路由器之间共享一个虚拟IP地址&#xff0c;确保即使一台路由器发生故障&#xff0c;网络依然能够正常运行&#xff0c;防止…

【JS学习】08. web API-事件进阶

Web APIs - 第3天 进一步学习 事件进阶&#xff0c;实现更多交互的网页特效&#xff0c;结合事件流的特征优化事件执行的效率 掌握阻止事件冒泡的方法理解事件委托的实现原理 事件流 事件流是对事件执行过程的描述&#xff0c;了解事件的执行过程有助于加深对事件的理解&…

Hadoop完全分布式环境搭建步骤

【图书介绍】《Spark SQL大数据分析快速上手》-CSDN博客 大数据与数据分析_夏天又到了的博客-CSDN博客 本文介绍Hadoop完全分布式环境搭建方法&#xff0c;这个Hadoop环境用于安装配置Spark。假设读者已经安装好Visual Box 7.0.6虚拟环境与一个CentOS 7虚拟机&#xff08;如果…

H7-TOOL的CAN/CANFD助手增加帧发送成功标识支持, 继续加强完善功能细节

2.27版本固件正式携带此功能&#xff0c;包括之前做的负载率检测和错误信息展示也将集成到这个版本固件中。 对于接收&#xff0c;我们可以直接看到效果&#xff0c;而发送不行&#xff0c;所以打算在发送的地方展示下发送成功标识。CAN发送不像串口&#xff0c;需要等待应答后…

ssm+jsp653基于Javaweb的网上花店系统的设计与实现

博主介绍&#xff1a;专注于Java&#xff08;springboot ssm 等开发框架&#xff09; vue .net php phython node.js uniapp 微信小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不…

操作系统如何执行,他究竟是个什么

硬件中断 所谓硬件中断&#xff0c;其实也是一个执行信号的过程&#xff0c;具体流程如下。 具体要执行什么方法&#xff0c;只需要拿着对应的信号访问中断向量表就就行比如 N就是像cpu发的中断信号。 时钟中断 但是这里面有一个叫做时钟源的东西&#xff0c;其实也是一个外…

音视频入门基础:FLV专题(24)——FFmpeg源码中,获取FLV文件视频信息的实现

一、引言 通过FFmpeg命令可以获取到FLV文件的视频压缩编码格式、色彩格式&#xff08;像素格式&#xff09;、分辨率、码率、帧率信息&#xff1a; 而由《音视频入门基础&#xff1a;FLV专题&#xff08;9&#xff09;——Script Tag简介》和《音视频入门基础&#xff1a;FLV专…

JMM内存模型(面试回答)

1.什么是JMM JMM就是Java内存模型(java memory model)。因为在不同的硬件生产商和不同的操作系统下&#xff0c;内存的访问有一定的差异&#xff0c;所以会造成相同的代码运行在不同的系统上会出现各种问题。所以Java内存模型(JMM)屏蔽掉各种硬件和操作系统的内存访问差异&…