热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

剑指Offer44.反转字符串中的单词

题目描述:牛客网新员工Fish每天早上都会拿着一本英文杂志,在本子上写下一些句子。他的同事Cat对这些句子非常感兴趣,但发现这些句子的单词顺序被反转了。例如,“student.aamI”实际上是“Iamastudent.”。Cat请求你帮助他恢复这些句子的正常顺序。

剑指Offer 44. 反转字符串中的单词

题目描述

牛客网最近迎来了一位新员工Fish,每天早晨他都会拿着一本英文杂志,并在本子上写下一些句子。他的同事Cat对这些句子非常感兴趣,但发现这些句子的单词顺序被反转了。例如,“student. a am I”实际上是“I am a student.”。Cat请求你帮助他恢复这些句子的正常顺序。

方法一:使用正则表达式分割字符串

通过空格分割字符串后,使用StringBuilder从后往前遍历数组并拼接。
注意点:使用trim()方法去除前后导空格,单词之间可能有多个空格,因此必须使用正则表达式来分割,避免单纯使用空格分割导致的问题。

1 class Solution {2 public String reverseWords(String s) {3 if(s == null || s.trim().length() == 0){4 return "";5 }6 // 用正则表达式分割成数组,处理多个空格7 String[] splits = s.trim().split("\s+");8 // 使用StringBuilder进行拼接9 StringBuilder sb = new StringBuilder();10 for(int i = splits.length - 1; i >= 0; i--){11 sb.append(splits[i]);12 if(i > 0){13 sb.append(" ");14 }15 }16 return sb.toString();17 }18 }

LeetCode运行时间:8 ms - 16.63%,空间:39.3 MB - 14.95%

复杂度分析:

时间复杂度:split()函数的时间复杂度为O(n),遍历数组的时间复杂度为O(n),总的时间复杂度为O(n)。

空间复杂度:需要一个额外的数组来存放单词,因此空间复杂度为O(n)。使用栈实现倒序会增加一个O(n)的空间复杂度。

方法二:使用空格分割字符串并过滤空串

使用split()函数分割字符串时仍使用空格,但在拼接结果字符串时需判断是否为空串,是则跳过。

1 class Solution {2 public String reverseWords(String s) {3 if(s == null || s.trim().length() == 0){4 return "";5 }6 // 用空格分割成数组7 String[] splits = s.trim().split(" ");8 // 使用StringBuilder进行拼接9 StringBuilder sb = new StringBuilder();10 for(int i = splits.length - 1; i >= 0; i--){11 if("".equals(splits[i])){12 continue;13 }14 sb.append(splits[i]);15 if(i > 0){16 sb.append(" ");17 }18 }19 return sb.toString();20 }21 }

LeetCode执行用时:1 ms - 100.00%,空间:38.9 MB - 57.82%,运行时间显著减少。

复杂度分析:

时间复杂度:split()函数的时间复杂度为O(n),遍历数组的时间复杂度为O(n),总的时间复杂度为O(n)。

空间复杂度:需要一个额外的数组来存放单词,因此空间复杂度为O(n)。使用栈实现倒序会增加一个O(n)的空间复杂度。

方法三:双指针法

不使用split()函数,从后往前遍历字符串,获取单词并添加到结果字符串中。

1 class Solution {2 public String reverseWords(String s) {3 if(s == null || s.trim().length() == 0){4 return "";5 }6 s = s.trim();7 // 两个指针,i 和 j,初始时都在末尾8 int i = s.length() - 1, j = i;9 StringBuilder sb = new StringBuilder();10 while(i >= 0){11 // 让i指针向前查找,直到遇到第一个空格12 while(i >= 0 && s.charAt(i) != ' '){13 i--;14 }15 // 截取[i+1, j+1)的子串到sb16 sb.append(s.substring(i+1, j+1) + " ");17 // 跳过单词间的多余空格18 while(i >= 0 && s.charAt(i) == ' '){19 i--;20 }21 j = i;22 }23 return sb.toString().trim();24 }25 }

LeetCode执行用时:3 ms - 65.01%,空间:39.2 MB - 16.37%

复杂度分析:

时间复杂度:遍历了一遍字符串,因此时间复杂度为O(n)。
空间复杂度:O(1)。

参考来源:https://leetcode-cn.com/problems/fan-zhuan-dan-ci-shun-xu-lcof/solution/mian-shi-ti-58-i-fan-zhuan-dan-ci-shun-xu-shuang-z/


推荐阅读
  • 浅析python实现布隆过滤器及Redis中的缓存穿透原理_python
    本文带你了解了位图的实现,布隆过滤器的原理及Python中的使用,以及布隆过滤器如何应对Redis中的缓存穿透,相信你对布隆过滤 ... [详细]
  • 2022年7月20日:关键数据与市场动态分析
    2022年7月20日,本文对当日的关键数据和市场动态进行了深入分析。主要内容包括:1. 关键数据的解读与趋势分析;2. 市场动态的变化及其对投资策略的影响;3. 相关经济指标的评估。通过这些分析,帮助读者更好地理解当前市场环境,为决策提供参考。 ... [详细]
  • 本指南从零开始介绍Scala编程语言的基础知识,重点讲解了Scala解释器REPL(读取-求值-打印-循环)的使用方法。REPL是Scala开发中的重要工具,能够帮助初学者快速理解和实践Scala的基本语法和特性。通过详细的示例和练习,读者将能够熟练掌握Scala的基础概念和编程技巧。 ... [详细]
  • 本文总结了JavaScript的核心知识点和实用技巧,涵盖了变量声明、DOM操作、事件处理等重要方面。例如,通过`event.srcElement`获取触发事件的元素,并使用`alert`显示其HTML结构;利用`innerText`和`innerHTML`属性分别设置和获取文本内容及HTML内容。此外,还介绍了如何在表单中动态生成和操作``元素,以便更好地处理用户输入。这些技巧对于提升前端开发效率和代码质量具有重要意义。 ... [详细]
  • 本文介绍了UUID(通用唯一标识符)的概念及其在JavaScript中生成Java兼容UUID的代码实现与优化技巧。UUID是一个128位的唯一标识符,广泛应用于分布式系统中以确保唯一性。文章详细探讨了如何利用JavaScript生成符合Java标准的UUID,并提供了多种优化方法,以提高生成效率和兼容性。 ... [详细]
  • MySQL初级篇——字符串、日期时间、流程控制函数的相关应用
    文章目录:1.字符串函数2.日期时间函数2.1获取日期时间2.2日期与时间戳的转换2.3获取年月日、时分秒、星期数、天数等函数2.4时间和秒钟的转换2. ... [详细]
  • 本文节选自《NLTK基础教程——用NLTK和Python库构建机器学习应用》一书的第1章第1.2节,作者Nitin Hardeniya。本文将带领读者快速了解Python的基础知识,为后续的机器学习应用打下坚实的基础。 ... [详细]
  • 三角测量计算三维坐标的代码_双目三维重建——层次化重建思考
    双目三维重建——层次化重建思考FesianXu2020.7.22atANTFINANCIALintern前言本文是笔者阅读[1]第10章内容的笔记,本文从宏观的角度阐 ... [详细]
  • 本文总结了Java初学者需要掌握的六大核心知识点,帮助你更好地理解和应用Java编程。无论你是刚刚入门还是希望巩固基础,这些知识点都是必不可少的。 ... [详细]
  • 本文详细介绍了Java反射机制的基本概念、获取Class对象的方法、反射的主要功能及其在实际开发中的应用。通过具体示例,帮助读者更好地理解和使用Java反射。 ... [详细]
  • Ihavetwomethodsofgeneratingmdistinctrandomnumbersintherange[0..n-1]我有两种方法在范围[0.n-1]中生 ... [详细]
  • 解决问题:1、批量读取点云las数据2、点云数据读与写出3、csf滤波分类参考:https:github.comsuyunzzzCSF论文题目ÿ ... [详细]
  • 本文介绍了一种在ANSI C中动态分配二维数组的方法。通过创建指针数组并为每个指针分配连续空间,可以灵活地管理内存。文章还讨论了一些常见的错误和注意事项。 ... [详细]
  • 在Android应用开发中,实现与MySQL数据库的连接是一项重要的技术任务。本文详细介绍了Android连接MySQL数据库的操作流程和技术要点。首先,Android平台提供了SQLiteOpenHelper类作为数据库辅助工具,用于创建或打开数据库。开发者可以通过继承并扩展该类,实现对数据库的初始化和版本管理。此外,文章还探讨了使用第三方库如Retrofit或Volley进行网络请求,以及如何通过JSON格式交换数据,确保与MySQL服务器的高效通信。 ... [详细]
  • 如何使用 net.sf.extjwnl.data.Word 类及其代码示例详解 ... [详细]
author-avatar
momosu1028_738_636
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有