【刷题第21天】 剑指 Offer 58 - I. 翻转单词顺序

74 阅读2分钟

“Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目描述:

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

 

示例 1:

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

示例 2:

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

二、思路分析:

这个题目说难不难,说简单不简单,他不是整体的字符串反转,而是单词翻转,通过空格来分割单词,那么也就是说符号是计算在单词之中的。另外字符串的前后可能存在空格,空格不在考虑范围之内。

因此本题目的算法可以总结为以下:

  • 先使用字符串的 trim 方法去除前后文多余的空格
  • 使用双指针法,初始时两个指针都指向 0,两个指针分别为 slow fast
  • fast 指针向后遍历,找到第一个空格位置,那么 slow -> fast 部分即存储了一个单词
  • 由于我们要倒置单词,因此我们可以使用栈数据结果,使用数组的 unshift 方法模拟
  • 当我们找到一个单词后,将该单词使用 unshift 方法插入到数组头部
  • 存完单词后,fast 继续后移找到第一个非空格,将 slow 指向这里,fast 重复上面流程
  • 最后使用数组的 join 方法转换成字符串输出

三、AC 代码:

var reverseWords = function(s) {
    let slow = 0;
    let len = s.length;
    let fast = 0;
    let res = [];

    // 先使用字符串的 trim 方法去除前后文多余的空格
    s = s.trim();

    while(slow < len) {
        // fast 指针找到第一个空格为止,获取到一个单词
        while(fast < len && s[fast] !== ' ')
            fast++;
        arr.unshift(s.slice(slow, fast));
        // fast 指针找到第一个非空格字符为止,重置 slow 字符
        while(fast < len && s[fast] === ' ')
            fast++;
        slow = fast;
    }
    return res.join(' ');
};

四、总结:

又是双指针,双指针真是简单题的神。