题目地址(151. 翻转字符串里的单词)

https://leetcode-cn.com/problems/reverse-words-in-a-string/

题目描述

  1. 给你一个字符串 s ,逐个翻转字符串中的所有 单词
  2. 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
  3. 请你返回一个翻转 s 中单词顺序并用单个空格相连的字符串。
  4. 说明:
  5. 输入字符串 s 可以在前面、后面或者单词间包含多余的空格。
  6. 翻转后单词间应当仅用一个空格分隔。
  7. 翻转后的字符串中不应包含额外的空格。
  8. 示例 1
  9. 输入:s = "the sky is blue"
  10. 输出:"blue is sky the"
  11. 示例 2
  12. 输入:s = " hello world "
  13. 输出:"world hello"
  14. 解释:输入字符串可以在前面或者后面包含多余的空格,但是翻转后的字符不能包括。
  15. 示例 3
  16. 输入:s = "a good example"
  17. 输出:"example good a"
  18. 解释:如果两个单词间有多余的空格,将翻转后单词间的空格减少到只含一个。
  19. 示例 4
  20. 输入:s = " Bob Loves Alice "
  21. 输出:"Alice Loves Bob"
  22. 示例 5
  23. 输入:s = "Alice does not even like bob"
  24. 输出:"bob like even not does Alice"
  25. 提示:
  26. 1 <= s.length <= 104
  27. s 包含英文大小写字母、数字和空格 ' '
  28. s 至少存在一个 单词
  29. 进阶:
  30. 请尝试使用 O(1) 额外空间复杂度的原地解法。

前置知识


公司

  • 暂无

思路

将整个字符串倒过来 然后再把单个单词倒过来
解题思路如下:

  • 移除多余空格
  • 将整个字符串反转
  • 将每个单词反转

举个例子,源字符串为:”the sky is blue “

  • 移除多余空格 : “the sky is blue”
  • 字符串反转:”eulb si yks eht”
  • 单词反转:”blue is sky the”

本题使用的是双指针来解决问题
翻转字符串 类似 344翻转字符串

关键点


代码

  • 语言支持:Java

Java Code:

  1. class Solution {
  2. public String reverseWords(String s) {
  3. //1. 清除多余空格
  4. StringBuilder sb = removeSpace(s);
  5. //2. 翻转整个字符串
  6. reverseString(sb, 0, sb.length()-1);
  7. //3. 翻转每个单词
  8. reverseEachWord(sb);
  9. return sb.toString();
  10. }
  11. private StringBuilder removeSpace(String s) {
  12. StringBuilder sb = new StringBuilder();
  13. int left = 0;
  14. int right = s.length() - 1;
  15. //去除两端空格
  16. while (s.charAt(left) == ' ') {
  17. left++;
  18. }
  19. while (s.charAt(right) == ' ') {
  20. right--;
  21. }
  22. //去除中间多余空格
  23. while (left <= right) {
  24. char charA = s.charAt(left);
  25. //如果charA!=空格 就把字符添加到sb中 或者当前sb最后一个不是空格 就把空格添加到里面
  26. if (charA != ' ' || sb.charAt(sb.length() - 1) != ' ') {
  27. sb.append(charA);
  28. }
  29. left++;
  30. }
  31. return sb;
  32. }
  33. private void reverseString(StringBuilder sb, int left, int right) {
  34. while (left < right) {
  35. //翻转整个数组
  36. char temp = sb.charAt(left);
  37. sb.setCharAt(left, sb.charAt(right));
  38. sb.setCharAt(right, temp);
  39. left++;
  40. right--;
  41. }
  42. }
  43. private void reverseEachWord(StringBuilder sb) {
  44. int left = 0;
  45. int right = 1;
  46. int size = sb.length();
  47. while (left < size) {
  48. //将当前的right移动到当前单词的末尾
  49. while (right < size && sb.charAt(right) != ' ') {
  50. right++;
  51. }
  52. //翻转单个单词
  53. reverseString(sb, left, right-1);
  54. //当前左端移到空格右边一格 右端移到当前左端的右边
  55. left = right+1;
  56. right = left +1;
  57. }
  58. }
  59. }

复杂度分析

令 n 为数组长度。

  • 时间复杂度:151. 翻转字符串里的单词 - 图1#card=math&code=O%28n%29&id=Nrbd1)
  • 空间复杂度:151. 翻转字符串里的单词 - 图2#card=math&code=O%28n%29&id=F9z5d)