剑指 Offer 58 - I. 翻转单词顺序(双指针;多次翻转)

2021年02月07日 周日 天气晴 【不悲叹过去,不荒废现在,不惧怕未来】



1. 题目简介

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

在这里插入图片描述

2. 题解

2.1 开辟一个新数组,利用双指针从后往前迭代

这种方法思路相对简单,代码比较容易实现,缺点就是需要开辟一个新的数组,空间复杂度为 O(n)

class Solution {
public:
    string reverseWords(string s) {
        int j = s.size() - 1, i = 0;
        string res;
        // 从后往前获取每个单词,在这个过程中,首尾的空格也被忽略掉了
        while(i>=0 && j>=0){
            while(j>=0 && s[j]==' ') --j;
            i = j;
            while(i>=0 && s[i]!=' ') --i;
            // 得到一个单词的首尾索引,添加到新建的字符串中
            res.append(s.substr(i+1, j-i));
            res.append(1,' ');
            j = i;
        }
        // 最后的结果尾部可能会有1个或2个空格,删除之
        j = res.size()-1;
        while(j>=0 && res[j]==' ') --j;
        return res.substr(0,j+1);
    }
};

2.2 空间复杂度为 O(1)的解法:先整体翻转,再局部翻转

首先除去字符串首尾的空格,然后整体翻转,最后再将每个单词局部翻转,就得到了最终结果。这种方法实现起来稍微复杂,但是空间复杂度只有 O(1)

class Solution {
public:
    string reverseWords(string s) {
        if(s.empty()) return s;
        // 删除字符串首尾的空格
        trim(s);

        int n = s.size();
        // 整体翻转字符串
        reverse(s, 0, n-1);

        int i = 0, j = 0;
        while(i<n && j<n){
            // 找到一个单词的首尾,进行局部翻转
            while(j<n && s[j] != ' ') ++j;
            reverse(s, i, j-1);
            i = j;
            
            // 让i指向下一个单词的首部
            while(i<n && s[i] == ' ') ++i;
            // 删除两个单词之间的空格
            s.erase(j,i-j-1);

            // 注意!!! !!!!!!
            // 删除空格之后,字符串的长度可能发生了变化,因此i、j、n的值都要进行更新
            i = j + 1;
            j = i;
            n = s.size();
        }
        return s;
    }

    // 删除字符串首尾的空格
    void trim(string& ss){
		if (ss.empty()) return;
		int i = 0;
		while (i < ss.size() && ss[i] == ' ') ++i;
		ss.erase(0, i);

		int j = ss.size() - 1;
		while (j >= 0 && ss[j] == ' ') --j;
		ss.erase(j+1);
    }

    // 翻转字符串
    void reverse(string& ss, int beg, int end){
        if(beg<0 || beg>=ss.size() || end<0 || end>=ss.size()) return;
        while(beg<end){
            char tmp = ss[beg];
            ss[beg] = ss[end];
            ss[end] = tmp;
            ++beg;
            --end;
        }
    }
};

参考文献

《剑指offer 第二版》

https://leetcode-cn.com/problems/fan-zhuan-dan-ci-shun-xu-lcof/solution/zi-jie-ti-ku-jian-58-i-jian-dan-fan-zhua-qwyg/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值