Leetcode刷题系列:翻转字符串里的单词

372 阅读2分钟

这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

题目

给你一个字符串 s ,逐个翻转字符串中的所有 单词单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 请你返回一个翻转 s 中单词顺序并用单个空格相连的字符串。

说明:

  • 输入字符串 s 可以在前面、后面或者单词间包含多余的空格。
  • 翻转后单词间应当仅用一个空格分隔。
  • 翻转后的字符串中不应包含额外的空格。

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/re…

示例:

示例 1:

输入:s = "the sky is blue" 输出:"blue is sky the"

示例 2:

输入:s = " hello world " 输出:"world hello" 解释:输入字符串可以在前面或者后面包含多余的空格,但是翻转后的字符不能包括。

示例 3:

输入:s = "a good example" 输出:"example good a" 解释:如果两个单词间有多余的空格,将翻转后单词间的空格减少到只含一个。

实现方案1 :使用Java 语言特性实现

实现步骤:

  1. 将字符串 通过 空格 切割成 单词数组
  2. 反转单词 (通过 数组转换成集合 利用 集合的反转函数实现)
  3. 重新通过 空格 拼接成 字符串
public String reverseWords(String s) {
    if (s == null || "".equals(s.trim())) {
        return "";
    }
    // 去除字符串 两头的空格
    s = s.trim();

    // 将数组按空格切割成数组
    String[] strings = s.split("\\s+");
    // 将数组转化成 集合
    List<String> list = Arrays.asList(strings);
    // 对集合数据进行反转
    Collections.reverse(list);
    // 集合通过 空格拼接成字符串
    return String.join(" ", list);
}

实现方案2 :数组+双指针

实现逻辑:

  1. 创建一个新的数组,来临时存储
  2. 创建 first、last 指针
  3. 倒序遍历字符串,定位单词的起止索引
  4. 根据起止索引,获取字符串存入临时数组
  5. 还原指针,进行重复循环 定位下一个单词
  6. 将新数组中合法数据生成新字符串
public String reverseWords2(String s) {
    s = s.trim();
    int len = s.length();

    if (s == null || len == 0) {
        return "";
    }
    char[] chars = new char[len];
    // 头
    int first = -1;
    // 尾
    int last = -1;
    // 新数组索引
    int index = 0;
    // 倒序遍历,定位单词起止索引
    for (int i = len - 1; i >= 0; i--) {
        char c = s.charAt(i);
        //
        if (c != ' ') {
            if (last == -1) {
                last = i;
            }
            if (i == 0) {
                first = i;
            }
        } else {
            if (last != -1) {
                first = i + 1;
            }
        }
        // 将读取到的单词,写入新的数组
        if (first >= 0 && last >= 0) {
            if (index > 0) {
                chars[index++] = ' ';
            }
            while (first <= last) {
                chars[index++] = s.charAt(first);
                first++;
            }
            // 还原指针
            first = last = -1;
        }
    }
    // 将最后得到的数组 转换成字符串
    return String.valueOf(chars, 0, index);
}

实现方案3: 双端队列

实现逻辑

  • 往双端队列头部依次存入每个单词
    • 通过遍历,将字符存储到缓冲区中
    • 当到达单词尾部时,将缓冲区中的单词,存放到 双端队列的头部
  • 从双端队列取出单词 即: 通过 String.join 将单词用 空格拼接
public String reverseWords4(String s) {
    int left = 0, right = s.length() - 1;
    Deque<String> d = new ArrayDeque<String>();
    StringBuilder word = new StringBuilder();
    while (left <= right) {
        char c = s.charAt(left);
        if (c != ' ') {
            word.append(c);
        } else {
            // 到达了单词结尾
            if (word.length() != 0) {
                // 将单词添加到队列的头部
                d.offerFirst(word.toString());
                word.setLength(0);
            }
        }
        ++left;
    }
    if (word.length() > 0) {
        d.offerFirst(word.toString());
    }
    return String.join(" ", d);
}

github 地址

案例地址

其他

广大 倔友 大佬们,如果看了文章!!! 请不要吝啬你们的点评!!! 如果有更好的解题思路 或者 我解题中不足的地方,文章书写不行的地方,希望大家能 给我评论指点一二!! 感谢大家!!