反转字符串中的单词

题目详情

反转字符串中的单词

给你一个字符串 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(n)

1
2
3
4
5
6
7
8
9
public static String reverseWords1(String s) {
if (s.isBlank()) {
return "";
}
String[] words = s.trim().split("\\s+");
List<String> strings = new ArrayList<>(Arrays.stream(words).toList());
Collections.reverse(strings);
return String.join(" ", strings);
}

image-20241111165619094

双指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public static String reverseWords(String s) {
// 将字符串转换为字符数组,以便进行操作
char[] chars = s.toCharArray();

// 移除字符串中的多余空格
int slow = 0; // 慢指针,指向下一个非空格字符应该放置的位置
//去掉空格操作,然后while循环里面一个单词一个单词赋值
for (int fast = 0; fast < chars.length; fast++) {
if (chars[fast] != ' ') { // 快指针找到非空格字符
if (slow != 0) { // 检查是否需要添加空格,只不在第一个单词前面添加空格
chars[slow++] = ' '; // 在单词之间添加一个空格
}
//找个一个不为空格的字符后,就开始赋值等到下一个空格字符去掉,然后再赋值
while (fast < chars.length && chars[fast] != ' ') {
chars[slow++] = chars[fast++]; // 复制非空格字符
}
}
}

// 反转整个字符串
reverse(chars, 0, slow - 1);

// 反转每个单词
int start = 0;
for (int i = 0; i < slow; i++) {
if (chars[i] == ' ') {
reverse(chars, start, i - 1); // 反转单词
start = i + 1; // 更新下一个单词的开始位置
}
}
// 反转最后一个单词
reverse(chars, start, slow - 1);

// 返回结果字符串,注意要截取实际有效的字符长度
return new String(chars, 0, slow);
}

// 辅助函数,用于反转字符数组中的指定部分
private static void reverse(char[] chars, int start, int end) {
while (start < end) {
char temp = chars[start];
chars[start++] = chars[end];
chars[end--] = temp;
}
}

image-20241111170439154