面试经典算法150题系列-反转字符串中的单词

news2024/9/25 3:19:43

反转字符串中的单词

给你一个字符串 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"
解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。

实现思路:

如果仅是实现字符串的反转比较容易,有两种实现思路:

第一种就是逆序输出。将字符串进行逆序遍历,每次遍历完一个单词后,则将其输出。边界条件就是字符串中间的空格。

第二种就是将字符串转换成列表。使用split进行分割,将每一个单词分隔开,构成一个字符串数组,然后逆序输出,即可得到反转的字符串。

然而,本题的难点在于对空格的处理,前后的空格,我们只需要使用trim()方法去掉,字符串中间的空格有的情况不只有有个,显然直接使用第一种思路和第二种思路都不太方便处理。这里我在堆字符串遍历前,对字符串进行了前后空格和中间的空格都进行了处理,将其分隔成为一个个规范的单词数组,然后逆序遍历数组,输出每一个单词并加上空格,遍历最后一个单词时不加空格。

实现代码:

 public  String reverseWords(String s) {
        // 1. 判空
        if (s == null || s.trim().isEmpty()) {
            return "";
        }

        // 2. 使用正则表达式去除空白字符并分割字符串
        String[] words = s.trim().split("\\s+");

        // 3. 使用StringBuilder来构建反转后的字符串
        StringBuilder reverseWords = new StringBuilder();

        // 4. 逆序遍历单词数组
        for (int i = words.length - 1; i >= 0; i--) {
            reverseWords.append(words[i]);
            // 在单词后添加空格,除了最后一个单词
            if (i > 0) {
                reverseWords.append(" ");
            }
        }

        // 5. 转换为String并去除尾部空格(如果有)
        return reverseWords.toString().trim();
    }

这里要注意的就是中间的空格处理,使用正则表达式`\\s+`将字符串分割成单词数组。`\\s+`表示匹配一个或多个空白字符,同时对于反转字符串操作使用了StringBuilder类,方便对字符串进行拼接操作(不懂这个类的可以在文章最后看知识补充)。

关于正则表达式,在最后一个单词的长度 一题中的最后有补充,大家可以看看,也可以顺便复习一下这一题。

实现思路2:多循环

       首先将输入字符串转换为字符数组,然后从字符串的末尾开始向前遍历,找到每个单词的起始和结束位置,并将单词的字符逆序复制到结果数组中。如果遇到空格,则在逆序复制的单词后面添加一个空格。最后,使用new String构造函数从结果数组中截取不包含最后一个空格的有效部分,作为最终的逆序字符串返回。

实现代码2:

public String reverseWords(String s) {
    // 将输入字符串转换为字符数组
    char[] s1 = s.toCharArray();
    // 创建一个新的字符数组,长度为原字符串长度加1,用于存储结果
    char[] s2 = new char[s1.length+1];
    // 初始化索引i为字符串的最后一个字符的位置
    int i =  s.length() - 1;
    // 初始化num用于记录结果字符串中字符的数量
    int num = 0;
    // 外层循环,从字符串的末尾开始向前遍历
    while (i >= 0) {
        // 内层循环1,跳过前面的空格直到找到非空格字符
        while(i>=0 && s1[i] == ' ') i--;
        // 记录当前单词的末尾位置
        int r = i;
        // 内层循环2,找到当前单词的开始位置
        while (i >= 0 && s1[i] != ' ') i--;
        // 内层循环3,将当前单词的字符逆序复制到s2数组中
        for(int j = i+1; j<=r;j++){
            s2[num++] = s1[j];
            // 如果是单词的最后一个字符,则在逆序复制后添加一个空格
            if(j==r){
                s2[num++] = ' ';
            }
        }
    }
    // 如果num为0,说明原字符串只包含空格,返回原字符串
    if(num==0){
        return s;
    // 否则,使用substring方法从s2数组中截取结果字符串
    }else{
        return new String(s2,0,num-1); // 最后一个字符是空格,所以num-1
    }
}

        第一种思路比较易于理解与实现,第二种思路执行效率相对高一些。

知识补充:

StringBuilder

StringBuilder是一个在Java中用于操作字符串的类,它提供了一种可变的字符序列,可以高效地进行字符串的拼接、插入、删除等操作。与String类相比,StringBuilder的主要优点是它允许在字符序列上进行修改,而不需要每次修改都创建一个新的字符串对象。

以下是StringBuilder的一些关键特性和常用方法:

  1. 可变性StringBuilder对象的内容可以被修改,这与String类形成对比,后者是不可变的。

  2. 线程安全性StringBuilder不是线程安全的。如果多个线程同时访问一个StringBuilder对象,而至少有一个线程写入该对象,那么应该通过同步或者使用StringBuffer(它是StringBuilder的线程安全版本)来确保线程安全。

  3. 构造函数StringBuilder提供了多种构造函数,可以创建一个空的StringBuilder对象,或者包含一个初始字符串的StringBuilder对象。

  4. 常用方法

    • append(Object obj):将指定对象的字符串表示形式追加到此字符序列的末尾。
    • insert(int offset, Object obj):在指定位置插入指定对象的字符串表示形式。
    • delete(int start, int end):删除从start到end(不包括end)的子序列。
    • reverse():将字符序列反转。
    • substring(int start) 或 substring(int start, int end):返回一个新字符串,它是此序列的子序列。
    • toString():返回一个新字符串,它包含此序列的字符。
  5. 性能:由于StringBuilder是可变的,因此在执行大量字符串操作时,它通常比String更高效。

  6. 使用场景:当你需要在循环中构建字符串或者需要频繁修改字符串内容时,使用StringBuilder是一个很好的选择。

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

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

相关文章

HarmonyOS--合理使用动画

一、概述 动画是应用开发中必不可少的部分&#xff0c;它可以使应用程序更加生动和易于互动&#xff0c;一方面可以提升用户体验、增强视觉吸引力&#xff0c;另一方面可以引导用户操作、提高信息传达效率。应用程序中&#xff0c;页面层级间的转场、点击交互、手势操控都可以添…

一刷代码随想录(图论8)

拓扑排序 软件构建 题意&#xff1a; 题目描述&#xff1a; 某个大型软件项目的构建系统拥有 N 个文件&#xff0c;文件编号从 0 到 N - 1&#xff0c;在这些文件中&#xff0c;某些文件依赖于其他文件的内容&#xff0c;这意味着如果文件 A 依赖于文件 B&#xff0c;则必须…

Semantic Kernel/C#:一种通用的Function Calling方法,文末附经测试可用的大模型

Funcion Calling介绍 函数调用允许您将模型如gpt-4o与外部工具和系统连接起来。这对于许多事情都很有用&#xff0c;比如为AI助手赋能&#xff0c;或者在你的应用程序与模型之间建立深度集成。 如果您了解或者使用过Semantic Kernel可能会发现除了OpenAI支持Function Calling…

cenos 7 安装 golang

1、下载地址 All releases - The Go Programming Languagehttps://golang.google.cn/dl/ 2、解压 tar -C /usr/local -zxf go1.14.3.linux-amd64.tar.gz 3、配置PATH 文件 /etc/profile&#xff08;全局&#xff09; 或 $HOME/.profile&#xff08;用户&#xff09; 或 ~/…

<数据集>安全背心识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;4185张 标注数量(xml文件个数)&#xff1a;4185 标注数量(txt文件个数)&#xff1a;4185 标注类别数&#xff1a;2 标注类别名称&#xff1a;[vest, no-vest] 序号类别名称图片数框数1vest222439942no-vest221552…

光性能 -- 入纤光功率

什么是入纤光功率&#xff1f; 入纤光功率&#xff1a;指业务光进入长纤时的单波光功率。如图所示&#xff0c;即为C点的光功率。 ​ 为什么要有入纤光功率 影响波分系统传输性能主要有四大因素&#xff1a; 光功率&#xff1a;表示能力的强弱&#xff0c;光模块能否接收。色…

[数据集][目标检测]玻璃瓶塑料瓶检测数据集VOC+YOLO格式8943张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;8943 标注数量(xml文件个数)&#xff1a;8943 标注数量(txt文件个数)&#xff1a;8943 标注…

stlink链接失败原因:虚拟机的虚拟接口的转接功能会导致主机的u盘等外设要选择是在主机还是虚拟机,串口,stlink等驱动也会

这就是为什么你连上电脑 stlink会与缓慢的闪烁不同&#xff0c;会很快的闪烁&#xff0c;很快的红灯闪烁是没链接上驱动的意思&#xff0c;缓慢的驱动是链接成功但与软件链接失败需要重插

软考:软件设计师 — 17.程序设计语言与语言处理程序基础

十七. 程序设计语言与语言处理程序基础 1. 程序设计语言概述 &#xff08;1&#xff09;编译程序与解释程序 编译型语言解释型语言共同点高级程序语言有词法分析、语法分析、语义分析过程不同点翻译程序编译器解释器是否生成目标代码生成不生成目标程序能否直接执行直接执行边…

掌控安全CTF-2024年8月擂台赛-ez_misc

题解&#xff1a; 题目给了一个流量包和一个加密的zip文件&#xff0c;我们首先打开流量包&#xff0c;很多流量&#xff0c;查看一下http协议&#xff0c;发现是个sql靶场&#xff0c;找到关键字样flag&#xff0c;得到一串字符&#xff1a; LJWXQ2C2GN2DAYKHNR5FQMTMPJMDER…

LabVIEW性能优化方法

在LabVIEW开发中&#xff0c;性能优化至关重要。合理的内存管理、并行处理、多线程优化、以及界面和代码的精简能够大幅提高程序效率&#xff0c;降低系统资源占用。下面将探讨LabVIEW性能优化的各个方面&#xff0c;提供实用技巧和建议&#xff0c;帮助开发者提升项目的执行速…

Python中排序算法之插入排序

1 插入排序算法原理 插入排序算法与《Python中排序算法之选择排序》中提到的选择排序算法类似&#xff0c;也是将要排序的数列分为两个子数列&#xff08;红色框数列和绿色框数列&#xff09;&#xff0c;不同之处在于插入排序算法从绿色框子数列中逐个选择数字&#xff0c;之…

读软件开发安全之道:概念、设计与实施12不受信任的输入

1. 不受信任的输入 1.1. 不受信任的输入可能是编写安全代码的开发人员最关心的问题 1.1.1. 最好将其理解为输入系统中的所有不受信任的输入 1.1.2. 来自受信任的代码的输入可以提供格式正确的数据 1.2. 不受信任的输入是指那些不受你控制&#xff0c;并且可能被篡改的数据&…

美发店会员系统设计解读之规格选择-SAAS本地化及未来之窗行业应用跨平台架构

一、请求产品信息 $.ajax({type:"get", //请求方式async:true, //是否异步url:"服务器",dataType:"json", //跨域json请求一定是jsonpjsonp: "cwpd_showData_dy_spec", //跨域请求的参数名&#xff0c;默认是callback//js…

创新互动体验RAG:利用角色化AI技术增强影视评论的沉浸感

创新互动体验RAG:利用角色化AI技术增强影视评论的沉浸感 目前已经搭建了一整套完整的角色对话链路,可以快速应用于各个角色扮演场景中。剧集中的评论场景是一个很好的角色扮演场景,期望能在优酷剧集的评论中,模拟角色性格,回复用户相关的评论并引导用户进一步互动,为优酷…

智能儿童对讲机语音交互,乐鑫ESP-RTC音视频通信,ESP32无线语音方案

儿童对讲机一种专为孩子们设计的通讯设备&#xff0c;可以让父母与孩子之间进行双向通讯&#xff0c;增强亲子关系&#xff0c;增强孩子的可玩性。 儿童对讲机近几年发展的比较快&#xff0c;通过无线WiFi及蓝牙通信技术&#xff0c;可以实现远程控制和语音交互功能&#xff0…

基于vue框架的便利店收银管理系统im2gw(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 开题报告内容 基于Vue框架的便利店收银管理系统开题报告 一、引言 随着零售业的快速发展&#xff0c;便利店作为日常生活中不可或缺的一部分&#xff0c;其运营效率和服务质量直接影响到顾客的购物体验和商家的盈利能力。便利店收银管理系统作为门店运营的…

hdfs的慢盘检测

这是我的第105篇原创文章 慢盘检测引入的背景 hdfs作为一个存储系统&#xff0c;势必会使用大量的磁盘。然而&#xff0c;在长期的使用过程中&#xff0c;磁盘也难免会磨损&#xff0c;出现损坏的磁道或扇区&#xff0c;导致磁盘读写变慢&#xff0c;IO操作耗时变长&#xff0c…

社群扫码进群完整可运营源码

源码介绍 社群扫码进群完整可运营源码&#xff0c;对接免签约支付接口&#xff0c;推广正常绑定下级。 1.安装上宝塔在配置这些环境就可以了 2.搭建环境Nginx MySQL 5.6 php7.2 3.php7.2安装扩展fileinfo redis Swoole sg11 4.服务器需要安装linux的系统 下载地址&#x…

学生宿舍管理小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;宿舍公告管理&#xff0c;学生管理&#xff0c;宿舍管理&#xff0c;后勤人员管理&#xff0c;楼栋信息管理&#xff0c;宿舍分配管理管理&#xff0c;退宿信息管理 微信端账号功能包括&#xff1a;系…