目录
反转字符串里的单词
给定一个字符串s,逐个反转字符串中的所有 单词。
单词是由非空格字符串组成的字符串,s中至少使用一个空格将字符串中的 单词 分隔开。
请你返回一个反转 s 中 单词顺序 并用单个空格相连的字符串。
说明:
输入字符串s可以在前面、后面或者单词间包含多余的空格
反转后单词应当应用一个空格分隔
反转后的字符串不应包含额外的空格
示例:
输入:s = " hello world "
输出: "world hello"
问题难度不是很大,和反转字符串其实差不多,下面我们从两个角度来解决该问题
方法1 :使用语言提供的方法来解决
在此,我们先使用java语言的特性来实现:
1)使用split 将字符串按空格分割成字符串数组;
2) 使用reverse 将字符串数组进行反转;
3) 使用join 方法将字符串数组重新拼成一个字符串
如下图:
具体实现代码如下:
class Solution {
// 方法一:正则匹配
public String reverseWords(String s) {
if(s == null || s.length() == 0) return null;
// 去掉头末空格
s = s.trim();
// 利用正则匹配分割单词
List<String> list = Arrays.asList(s.split("\\s+"));
Collections.reverse(list);
return String.join(" ", list); // 将列表重新变为字符串,用空格分开
}
}
但是这种方式毕竟用了语言特性,而没有考察到算法,所以面试时一般不会用,对于上面提到的功能,我们还是自己编写函数来实现吧!
方法2:自己实现上述功能
对于字符串可变的语言,就不需要额外开辟空间了,直接在字符串上原地实现。在这种情况下,反转字符和去除空格就可以放在一起完成了
具体实现代码如下:
class Solution {
// 方法二:自己编写函数实现功能
public String reverseWords(String s) {
StringBuilder sb = trimSpaces(s); // 去掉前后空格
reverse(sb, 0, sb.length()-1); // 反转整个字符串
reverserEachWords(sb); // 反转每个单词
return sb.toString(); // 返回转换后的字符串
}
public StringBuilder trimSpaces(String s){
int left = 0, right = s.length() - 1;
// 去掉开头和末尾的空格
while(left <= right && s.charAt(left) == ' '){
left++;
}
while(left <= right && s.charAt(right) == ' '){
right--;
}
// 去除字符串间多余的空白字符
StringBuilder sb = new StringBuilder();
while(left <= right){
char c = s.charAt(left);
if(c!=' ') sb.append(c); // 不为空格则直接加入
else if(sb.charAt(sb.length() - 1) != ' ') sb.append(c); // 若为空格则只加入一个
++left;
}
return sb;
}
// 翻转整个字符串
public void reverse(StringBuilder sb,int left, int right){
while(left <= right){
char tmp = sb.charAt(left);
sb.setCharAt(left++, sb.charAt(right));
sb.setCharAt(right--, tmp);
}
}
// 翻转每一个单词中的字符
public void reverserEachWords(StringBuilder sb){
int n = sb.length();
int start = 0, end = 0;
while(start < n){
// 循环至单词末尾
while(end < n && sb.charAt(end) != ' ') {
++end;
}
// 翻转该单词
reverse(sb, start, end-1);
// 更新start,寻找下一个单词
start = end + 1;
++end;
}
}
}