算法初探LeetCode-反转字符串中的单词

131 阅读2分钟

LeetCode151:反转字符串中的单词

给你一个字符串 s ,请你反转字符串中 单词 的顺序。

单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。

返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。

注意: 输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

示例 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<=s.length<=1041 <= s.length <= 10^4
  • s 包含英文大小写字母、数字和空格 ' '
  • s 中 至少存在一个 单词

思路分析

由题意分析:将s中出现的单词加入list中的过程:

  • 1、从头开始遍历,记录第一个单词的起始位置(单词的起始位置不一定为0,第一个单词的起始位置为起始的第一个不为' '的字符)

  • 2、记录完第一个单词的起始位置以后,再遍历剩下的元素,此处使用了while循环,因为for循环会自动i++,使用while循环我们可以自己控制i++

    • 当前字符为字母且下一个字符为空时,证明遇到了单词的结尾,将单词加入结果字符中
    • 当前字符和下一个字符都不为空时,则i++,如果当前单词或者下一个字符任一为空,则不进行i++
    • 当遍历到最后的字符时,将其加入结果中

最后逆序遍历list中的元素生成结果字符串

算法代码

public String reverseWords(String s) {

    if (s == null || s.length() < 2) {
        return s;
    }
    //将参数统一到前后都没有空格的状态
    s = s.trim();
    int len = s.length();
    int head = len - 1;
    int tail = head;
    boolean isWord = false; //true开始寻找单词开头,false连续空格,寻找单词尾
    StringBuilder strb = new StringBuilder();
    //逆向遍历字符串
    for (int i = len - 1; i >= 0; i--) {
        //首先寻找该单词tail位置,第一个非空字符
        if (s.charAt(i) != ' ') {
            if (!isWord) {
                tail = i;
                isWord = true;
            }
        }
        if (s.charAt(i) == ' ' || i == 0) {
            //该字符为空,单词开始or连续空格
            if (isWord) {
                //单词开始,截取并拼接结果;连续空格不处理,继续往前遍历
                head = (i == 0) ? -1 : i;
                strb.append(" ").append(s.substring(head + 1, tail + 1));
                isWord = false;
            }
        }
    }
    return strb.toString().trim();
}

结果详情

Snipaste_2023-02-21_20-46-27.png

算法复杂度

  • 空间复杂度:O(1)O(1)
  • 时间复杂度:O(n)O(n)

掘金(JUEJIN)一起进步,一起成长!