题目:

给你一个字符串 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 中 至少存在一个 单词

进阶:如果字符串在你使用的编程语言中是一种可变数据类型,请尝试使用 O(1) 额外空间复杂度的 原地 解法。

来源:力扣(LeetCode) 和  剑指 Offer 58 - I. 翻转单词顺序

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

一、暴力求解

1.先使用trim()减去字符串两端的空格;

2.使用split()将字符串按空格分割成字符串数组;

3.使用reverse()将字符串数组进行反转;

4.最后用join()将字符串数组拼接成一个字符串。

代码:

二、双指针

1.将字符串转换成字符数组;

2.设置两个指针left和right分别指向数组的初始位置和结束位置,裁剪掉两端的空格;

3.借助index指针,从right位置开始向左遍历,直到遇到空格,然后在[index+1, right]范围内遍历字符将字符放在stringBuilder中,并添加空格;

4.然后跳过中间连续的空格,当index有字符时,代表遇到下一个字符串的结束位置,改变right的值,index继续向左遍历,直到遇到空格,后面与步骤3一致进行添加;

5.返回string类型的字符串。

 代码:

 1 class Solution {
2 public String reverseWords(String s) {
3 char[] s1 = s.toCharArray();
4 StringBuilder s2 = new StringBuilder();
5 int left = 0, right = s.length()-1;
6 //去掉字符串左右两端的空白
7 while(s1[left] == ' ') {
8 left++;
9 }
10 while(s1[right] == ' ') {
11 right--;
12 }
13 //添加单词
14 while (left <= right){
15 int index = right;
16 while(index >= left && s1[index] != ' ') {
17 index--;
18 }
19 //当index所指为空格时,后面一位才是当前单词的初始位置
20 for(int i = index+1; i <= right; i++){
21 s2.append(s1[i]);
22 }
23 //不是最后一个单词时都需要添加空格
24 if(index > left) s2.append(' ');
25 //跳过中间的空格,开始寻找下一个单词的位置
26 while(index >= left && s1[index] == ' '){
27 index --;
28 }
29 right = index;
30 }
31 return s2.toString();
32 }
33 }

或者:

 1 class Solution {
2 public String reverseWords(String s) {
3 s = s.trim();
4 StringBuilder sb = new StringBuilder();
5 int fast = s.length() - 1, slow = fast;
6 while (fast >= 0){
7 while (fast >= 0 && s.charAt(fast) != ' ') fast--;
8 sb.append(s.substring(fast + 1, slow + 1) + " ");
9 while (fast >= 0 && s.charAt(fast) == ' ') fast--;
10 slow = fast;
11 }
12 return sb.toString().trim();
13
14 }
15 }

小知识:

1.将数组转化成List集合的方法,此方法得到的list长度是不可变的

 List<String> list = Arrays.asList("aa","bb","cc");

(1)该方法适用于对象型数据的数组(String、Integer...)

对象类型(String型)的数组数组使用asList(),正常
1 String[]strings = {f"aa","bb","cc"};
2 List<String> stringList = Arrays.asList(strings);
//String类型数组使用asList(),正常:aa bb cc

(2)该方法不建议使用于基本数据类型的数组(byte,short,int,long,float,double,boolean)

 基本数据类型的数组使用asList(),出错
1 int[] ints = new int[]{1,2,3};
2 List intList = Arrays.asList(ints);
//基本数据类型的数组使用asList(),出错(输出的是一个引用,把ints当成一个元素了):[I@1540e19d这样遍历才能正确输出: 1 2 3

(3)该方法将数组与List列表链接起来:当更新其一个时,另一个自动更新

(4)不支持add()、remove()、clear()等方法
2.split("\\s+")和split("+"):

\s 表示:匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]
+ 表示:匹配前面的子表达式一次或多次。
\s+ 表示:以空格、换行符、回车为分割线,相邻的多个空格、换行符、回车仍然视为只有一个,分隔后返回字符数组

3.Collections类是集合类的一个工具类其中提供了一系列静态方法,用于对集合中元素进行排序、搜索以及线程安全等各种操作,常用方法:

public class test{
public static void main(String[] args){
List list = new ArrayList();
list.add("b");
list.add("s");
list.add("t");
list.add("a");
//1.对集合进行排序--[a,b,s,t]
Collections.sort(list);
System.out.println(list);
//2.对集合进行随机排序--[s,a,t,b]
Collections.shuffle(list);
System.out.println(list);
//3.查找指定集合中的元素,返回所查找元素的索引--1
int n = Collections.binarySearch(list, "s");
System.out.println(n);
//4.反转集合中的元素--[t,s,b,a]
Collections.reverse(list);
System.out.println(list);
//5.替换某元素,若要替换的值存在返回true,反之返回false --true,[b,s,t,f,p]
System.out.println(Collections.replaceAll(list, "a","f p"));
//6.集合中的元素向后移m个位置,在后面被遮盖的元素循环到前面来--[a,b,s,t]
Collections.rotate(list, 1);
System.out.println(list);
//7.将集合n中的元素全部赋值到list中,并且覆盖相应索引的元素--[one, two, three, a]
List n = Arrays.asList("one two three".split(" "));
Collections.copy(list, n)
System.out.println(list);
//8.交换集合中指定元素索引的位置--[b, s, a, t]
Collections.swap(list, 2, 3);
System.out.println(list); }
}

4.Java String join()方法返回一个新字符串,该字符串具有给定的元素和指定的分隔符。

String.join(CharSequence delimiter,CharSequence... elements)将elements用指定的字符串delimeter连接起来
delimiter:与元素连接的连接符
elements:连接的元素
...: 表示可以有一个或多个CharSequence(字符序列)。
注意: join()是静态方法。您无需创建字符串对象即可调用此方法。使用类名称String调用该方法。
例如:
String message = String.join("-", "java", "is", "cool"); //返回的是“java-is-cool”

5.char[] s1 = s.toCharArray():将字符串s转换成一个char类型的数组。

6.在使用无参构造来构造StringBuilder对象:

StringBuilder s2 = new StringBuilder();

Java String、StringBuffer 和 StringBuilder 的区别:

  • string字符串常量,字符串长度不可变,每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响;
  • stringBuffer:字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用 StringBuffer,如果想转成 String 类型,可以调用 StringBuffer 的 toString() 方法;
  • stringBuilder:字符串变量(非线程安全)。在内部,StringBuilder 对象被当作是一个包含字符序列的变长数组,在执行速度方面的比较:StringBuilder > StringBuffer.

使用原则:

  • 如果要操作少量的数据用 :String
  • 单线程操作字符串缓冲区 下操作大量数据 : StringBuilder
  • 多线程操作字符串缓冲区 下操作大量数据 : StringBuffer

7.toString()方法将对象转换为字符串。

力扣151(java)-颠倒字符串中的单词(中等)的更多相关文章

  1. 力扣(LeetCode)字符串中的单词数 个人题解

    统计字符串中的单词个数,这里的单词指的是连续的不是空格的字符. 请注意,你可以假定字符串里不包括任何不可打印的字符. 示例: 输入: "Hello, my name is John" ...

  2. 力扣(LeetCode)字符串中的第一个唯一字符 个人题解

    给定一个字符串,找到它的第一个不重复的字符,并返回它的索引.如果不存在,则返回 -1. 案例: s = "leetcode" 返回 0. s = "loveleetcod ...

  3. java翻转字符串中的单词

    效果: 输入: "java and python" 输出: "avaj dna nohtyp" 代码: 版本1: 不考虑字符串开头有空格,单词间有多个空格空格的 ...

  4. 力扣题目汇总(反转字符串中的单词,EXCEL表列序号,旋置矩阵)

    反转字符串中的单词 III 1.题目描述 给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序. 示例 1: 输入: "Let's take LeetCode ...

  5. java截取字符串中的数字

    java从字符串中提取数字 随便给你一个含有数字的字符串,比如: String s="eert343dfg56756dtry66fggg89dfgf"; 那我们如何把其中的数字提取 ...

  6. 三种java 去掉字符串中的重复字符函数

    三种java 去掉字符串中的重复字符函数 public static void main(string[] args) { system.out.println(removerepeatedchar( ...

  7. java通过StringToKenizer获取字符串中的单词根据空格分离-简写版

    public class StringToKenizer { public static void main(String[] args) { String strin = "Hello J ...

  8. java通过StringToKenizer获取字符串中的单词根据空格分离-详情版

    public class DaXie { public static void main(String[] args) { String strin = "Hello Java World! ...

  9. java 判断字符串中是否包含中文并过滤掉中文

      java判断字符串中是否包含中文并过滤掉中文 CreateTime--2017年9月6日08:48:59 Author:Marydon 1.判断字符串中是否包含中文方法封装 /** * 判断字符串 ...

  10. 使用 Java 查找字符串中出现次数最多的字符以及出现的次数?

    使用 Java 查找字符串中出现次数最多的字符以及出现的次数? import java.util.HashMap; import java.util.Map; public class TestStr ...

随机推荐

  1. vscode sftp 代码同步到服务器

    然后执行 ctrl+shift+p ,搜索 SFTP:Config 回车后,会生成一个".vscode/sftp.json",这个就是配置文件 参考:VsCode SFTP插件详细 ...

  2. 恒玄科技BES250解决方案之双耳链接调试总结和源码分析

    一 前言 bes2500芯片在tws耳机应用十分广泛,该芯片有着资源强大,音质好,大厂背书等特色.吸引了不少粉丝跟随. 最近在调试该芯片的tws配对流程,花费了一些时间,踩了一些坑,这里做一个总结和备 ...

  3. [vscode]使用cmake时将命令行参数传递给调试目标

    一.简介 本文介绍了在vscode中使用cmake工具时,如何传递参数给编译目标的方法. 前提:使用vscode+cmake编译C/C++程序. 二.方法 在.vscode/目录下新建settings ...

  4. FreeRTOS教程7 事件组

    1.准备材料 正点原子stm32f407探索者开发板V2.4 STM32CubeMX软件(Version 6.10.0) Keil µVision5 IDE(MDK-Arm) 野火DAP仿真器 XCO ...

  5. Linux快速入门(六)Linux网络管理

    ping ping命令用于测试两台主机之间是否可以通信,一般情况下会使用ping www.baidu.com来测试网络连通性,如果不指定发送包的个数默认是一直发送数据包,可以使用Ctrl+C停止.网络 ...

  6. KingbaseES V8R6 sslinfo 插件

    前言 KingbaseES对使用SSL 连接加密客户端/服务器通讯的本地支持,可以增加数据传输安全性. 本文展示配置ssl连接,并通过安装一个插件验证ssl加密认证使用. 一.配置ssl连接过程: s ...

  7. Python 基于 xlsxwriter 实现百万数据导出 excel

    追加导出 + 自动切换 sheet ️ excel 中的每个 sheet 最多只能保存 1048576 行数据 # 获取项目的根路径 rootPath curPath = os.path.abspat ...

  8. 03 jQuery属性控制

    03 jQuery属性控制 属性相关的控制主要有以下几个功能 val() => 处理value属性 text() => 处理innerText html() => 处理innerHT ...

  9. #KMP,容斥,dp#洛谷 5770 [JSOI2016] 无界单词

    题目传送门 分析 显然如果存在长度大于一半的border那么必然存在小于一半的 border,所以容斥一下, 设 \(dp[i]\) 表示长度为 \(i\) 的不存在公共前后缀的字符串个数,那么 \( ...

  10. #后缀数组,单调队列#洛谷 2852 [USACO06DEC]Milk Patterns G

    题目 给定一个长度为\(n\)的字符串,求出现至少\(k\)次的最长子串长度 分析 由于后缀排序后的LCP才是最长的,既然要求至少\(k\)次, 实际上也就是维护长度为\(k\)的height数组最小 ...