剑指 Offer 58 - I. 翻转单词顺序

176 阅读3分钟

剑指 Offer 58 - I. 翻转单词顺序

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

1、题目📑

输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. ",则输出"student. a am I"。

实例1

输入: "the sky is blue"

输出: "blue is sky the"

实例2

输入: " hello world! "

输出: "world! hello"

解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。

实例3

输入: "a good example"

输出: "example good a"

解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

说明

  • 无空格字符构成一个单词。
  • 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
  • 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

注意:本题与主站 151 题相同:leetcode-cn.com/problems/re…

注意:此题对比原题有改动

2、思路🧠

方法一:java内置类StringBuffer

  1. 将字符串使用 trim() 函数将字符串前后的空格去掉,再进行空格分割处理。
  2. 需要注意多个空格分隔之后为 "" 为空的字符串,所以要进行特殊情况的处理。
  3. 利用 StringBuffer 对每个字符串进行去空格拼接,即 trim() 处理。
  4. 切记在最后一个单词处理的时候,不进行添加尾部 " "

方法二:双指针

  1. 使用 trim() 函数将字符串前后的空格去掉
  2. 使用双指针倒叙遍历字符串,记录该单词的左边界和右边界
  3. 确定好边界利用字符串自带的函数 substring() 截取指定的单词
  4. 利用 StringBuffer 进行拼接。

这里需要注意的是函数 substring() 是一个左开右闭的区间类似与[1,2)这种形式,所以在考虑截取的时候需要注意单词的前后位置。

废话少说~~~~~上代码!

3、代码👨‍💻

第一次commit AC

class Solution {
    public String reverseWords(String s) {
        StringBuffer sb = new StringBuffer();
        String str[] = s.trim().split(" ");
        
        for(int i = str.length - 1; i >= 0; i--) {
            if(str[i].equals("")) continue;

            if(i==0) {
                sb.append(str[i].trim());
            }else {
                sb.append(str[i].trim()).append(" ");
            }
        }

        return sb.toString();
    }
}

时间复杂度:O(N) trim() 为O(N),split()为O(N)

空间复杂度:O(N) 快速排序的递归深度平均为 O(logN) ,最差情况为 O(N)。

第二次commit AC

class Solution {
    public String reverseWords(String s) {
        StringBuffer sb = new StringBuffer();
        s = s.trim();
        int l = s.length() - 1;
        int r = s.length() - 1;
        while(l >= 0) {
            while(l >=0 && s.charAt(l) != ' ') l--;
            sb.append(s.substring(l+1, r+1).trim()).append(" ");
            while(l >=0 && s.charAt(l) == ' ') l--;
            r = l;
        }
        return sb.toString().trim();
    }
}

时间复杂度:O(N) N 为字符串 s 的长度

空间复杂度:O(N) StringBuffer(Java) 中的字符串总长度 ≤ N

image-20220401185144614

4、总结

该题目对字符串的各种操作API一点要熟悉并且透彻的了解,每一次操作,每一步的过程以及产生的结果。

❤️‍来自专栏《LeetCode基础算法题》欢迎订阅❤️‍

厂长写博客目的初衷很简单,希望大家在学习的过程中少走弯路,多学一些东西,对自己有帮助的留下你的赞赞👍或者关注➕都是对我最大的支持,你的关注和点赞给厂长每天更文的动力。

对文章其中一部分不理解,都可以评论区回复我,我们来一起讨论,共同学习,一起进步!

原题链接:剑指 Offer 58 - I. 翻转单词顺序