持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情
题目
输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. ",则输出"student. a am I"。 " hello world! " ->"world! hello";"a good example" -> "example good a"
解题思路
根据题意可知以下几点:
- 字符串需要倒装输出。
- 句子倒装但单词非倒装输出。
- 单词和单词之间空格只保留一个。
双指针解法
又使用到双指针解法,定义两个下标值来指定当前在字符串上移动位置。
- 双指针起始位置都在尾部。
- 首先移动left指针,先排除掉空格直到非空格为止。
- 然后移动left指针直到遇到空格为止。
- 使用substring截取到单词字段,然后将right指针指向left位置。
- 继续移动left指针重复上述操作,一直循环直到left指针指向0下标为止。
public String reverseWords(String s) {
// 双指针
int left = s.length() - 1;
int right = left; // 起始位置都在尾部
StringBuilder stringBuilder = new StringBuilder();
while(left > 0 && s.charAt(left) == ' ') left --;
right = left;
while(left >= 0){
while(left >= 0 && s.charAt(left) != ' ') left --; // 直到为空格
stringBuilder.append(s.substring(left + 1,right + 1)).append(" ");//截取单词
while(left >= 0 && s.charAt(left) == ' ') left --; // 去空格
right = left;
}
if(stringBuilder.length() > 0)
stringBuilder.deleteCharAt(stringBuilder.length()-1); // 去掉多余的空格
return stringBuilder.toString();
}
巧用语法解法
巧解法使用到String类方法以及List类方法。
- 先用trim去掉首尾多余空格。
- 正则手段分割出每个单词组装成List。
- 列表集合reverse倒序重新排序。
- join方法重新为每个单词间加空格。
熟悉API采用巧解能够快速得到解题思路,主要对于语言够了解就能实现。
public String reverseWords(String s) {
// 除去开头和末尾的空白字符
s = s.trim();
// 正则匹配连续的空白字符作为分隔符分割
List<String> words = Arrays.asList(s.split("\s+"));
Collections.reverse(words);
return String.join(" ", wordList);
}
分割倒序解法
分割倒序法综合了上述两种解法,字符串分割加上倒序并运用API方法。
- 先用trim去掉首尾多余空格并分割字符串得到每块单词。
- 倒序遍历每个单词块字符重新拼接字符串。
- 最后通过trim去掉尾部多余空格。
public String reverseWords(String s) {
String[] strs = s.trim().split(" "); // 删除首尾空格,分割字符串
StringBuilder res = new StringBuilder();
for(int i = strs.length - 1; i >= 0; i--) { // 倒序遍历单词列表
if(strs[i].equals("")) continue; // 遇到空单词则跳过
res.append(strs[i] + " "); // 将单词拼接至 StringBuilder
}
return res.toString().trim(); // 转化为字符串,删除尾部空格,并返回
}
参考
- 来源:力扣(LeetCode)