zoukankan      html  css  js  c++  java
  • 剑指offer 44. 翻转单词序列

    44. 翻转单词序列

    题目描述

    牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?

    思路一:

    用空格分割字符串后用StringBuilder变量从后往前遍历数组拼接
    注意点:要用trim() 方法去除前后导空格, 并且单词之间可能有多个空格,所以必须使用正则表达式来分割,单纯的使用空格分割后面添加的时候必须判断是否是空串
     1 class Solution {
     2     public String reverseWords(String s) {
     3         if(s == null || s.trim().length() == 0){
     4             return "";
     5         }
     6         // 用空格分割成数组,空格可能有很多个,所以要用正则表达式
     7         String[] splits = s.trim().split("[ ]+");  
     8         // 使用StringBilder进行拼接
     9         StringBuilder sb = new StringBuilder("");
    10         for(int i = splits.length - 1; i >= 0; i--){
    11             sb.append(splits[i]);
    12             if(i > 0){
    13                 sb.append(" ");
    14             }
    15         }
    16         return sb.toString();
    17     }
    18 }

    leetcode 运行时间为8 ms - 16.63%, 空间为39.3 MB - 14.95%

    复杂度分析:

    时间复杂度:split()函数的时间复杂度为O(n), 一次遍历数组的时间复杂度为O(n), 所以总的时间复杂度为O(n)

    空间复杂度:需要一个额外的数组来存放单词,所以空间复杂度为O(n),倒序可以使用栈来实现,不过那样会增加一个O(n)的空间复杂度

     思路二:

    在使用split()函数分割字符串时仍然使用空格,而非正则表达式,因为正则表达式效率比较低,但是在append()到结果字符串时要判断是否是空串,是则跳过

     1 class Solution {
     2     public String reverseWords(String s) {
     3         if(s == null || s.trim().length() == 0){
     4             return "";
     5         }
     6         // 用空格分割成数组,空格可能有很多个,所以要用正则表达式
     7         String[] splits = s.trim().split(" ");  
     8         // 使用StringBilder进行拼接
     9         StringBuilder sb = new StringBuilder("");
    10         for(int i = splits.length - 1; i >= 0; i--){
    11             if("".equals(splits[i])){
    12                 continue;
    13             }
    14             sb.append(splits[i]);
    15             if(i > 0){
    16                 sb.append(" ");
    17             }
    18         }
    19         return sb.toString();
    20     }
    21 }
    leetcode 执行用时:1 ms - 100.00%, 空间为 38.9 MB - 57.82%,可以看到,运行时间短了很多

    复杂度分析:

    时间复杂度:split()函数的时间复杂度为O(n), 一次遍历数组的时间复杂度为O(n), 所以总的时间复杂度为O(n)

    空间复杂度:需要一个额外的数组来存放单词,所以空间复杂度为O(n),倒序可以使用栈来实现,不过那样会增加一个O(n)的空间复杂度

    思路三:

    不使用split()函数,从后往前倒着遍历,获取到单词就添加到结果字符串中

     1 class Solution {
     2     public String reverseWords(String s) {
     3         if(s == null || s.trim().length() == 0){
     4             return "";
     5         }
     6         s = s.trim();
     7         // 两个指针,i 和 j, 初始时都在末尾
     8         int i = s.length() - 1, j = i;
     9         StringBuilder sb = new StringBuilder("");
    10         while(i >= 0){
    11             // 让i指针向前查找,查找到但此前的第一个空格
    12             while(i >= 0 && s.charAt(i) != ' '){
    13                 i--;
    14             }
    15             // 截取[i+1, j+1)的子串到sb
    16             sb.append(s.substring(i+1, j+1) + " ");
    17 
    18             // 跳过单词间多余的空格
    19             while(i >= 0 && s.charAt(i) == ' '){
    20                 i--;
    21             }
    22             j = i;
    23         }
    24         return sb.toString().trim();
    25     }
    26 }
    leetcode 执行用时:3 ms - 65.01%, 空间为:39.2 MB - 16.37%

    复杂度分析:

    时间复杂度:遍历了一遍字符串,所以时间复杂度为O(n)
    空间复杂度:O(1)

    思路二和思路三均参考自:https://leetcode-cn.com/problems/fan-zhuan-dan-ci-shun-xu-lcof/solution/mian-shi-ti-58-i-fan-zhuan-dan-ci-shun-xu-shuang-z/

  • 相关阅读:
    Shiro缓存整合EhCache
    Shiro缓存整合EhCache
    Shiro缓存整合EhCache
    Shiro缓存整合EhCache
    Shiro缓存整合EhCache
    Eclipse中配置Ehcache提示信息
    Eclipse中配置Ehcache提示信息
    Eclipse中配置Ehcache提示信息
    基本类型包装类
    StringBuilder类
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/12601624.html
Copyright © 2011-2022 走看看