leetcode 151 翻转字符串里的单词

题目描述

给定一个字符串,逐个翻转字符串中的每个单词。

示例 1:
输入: “the sky is blue”
输出: “blue is sky the”

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

示例 3:
输入: “a good example”
输出: “example good a”
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

说明:
无空格字符构成一个单词。
输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

进阶:
请选用 C 语言的用户尝试使用 O(1) 额外空间复杂度的原地解法。

解题思路

1.将字符串中的每个单词都存储在栈中,然后再从栈中拿出单词构成新的字符串。
空间复杂度O(n)
时间复杂度O(n)

// C++ version
// 利用字符流(sstream)可以更加方便的解决空格问题
class Solution {
public:
    string reverseWords(string s) {
        stack<string> sc;
        string temp, res = "";
		int l;
		
        for(int i = 0; i < s.length(); i++)
        {
			while(i != s.length() && s[i] == ' ')
				i++;
			l = i;
			while(i != s.length() && s[i] != ' ')
				i++;
			if(l != s.length())
			{
				temp = s.substr(l, i - l);
				sc.push(temp);
			}
        }

        while(!sc.empty())
        {
            res += sc.top();
            res += ' ';
            sc.pop();
        }
        return res.size() == 0 ? res : string(res.begin(), res.end() - 1);
    }
};

class Solution {
public:
    string reverseWords(string s) {
        stringstream ss(s);
        string temp, res = "";
        stack<string> sc;
        while(ss >> temp)
            sc.push(temp);
        while(!sc.empty())
        {
            res += sc.top() + ' ';
            sc.pop();
        }
        // 避免res为空字符串带来的错误
        return res.size() == res ? "" : string(res.begin(), res.end() - 1);
    }
};

2.先将整个字符串反转,然后再逐单词反转。
时间复杂度O(n)
空间复杂度O(1)

// C++ version
class Solution {
public:
    string reverseWords(string s) {
    	// 反转字符串
        reverse(s.begin(), s.end());
        // 处理头部空格和尾部空格  
        int head = 0;
        int tail = s.length() -1;

        while(head <= tail && s[head] == ' ')
            head++;
        while(head <= tail && s[tail] == ' ')
            tail--;
        if(head > tail)
            return "";
		
		// 逐单词反转
        int l;
        for(int i = head; i <= tail; i++)
        {
            while(i != tail + 1 && s[i] == ' ')
                i++;
            l = i;
            while(i != tail + 1 && s[i] != ' ')
                i++;
            reverse(s.begin() + l, s.begin() + i);
        }
		
		// 处理中间空格
        l = head;
        for(int i = head; i <= tail ; i++)
        {
            if(i < tail && s[i] == ' ' && s[i + 1] == ' ')
                continue;
            s[l++] = s[i];
        }

        return string(s.begin() + head, s.begin() + l);
    }
};
// C version
void reverse(char* s, int x, int y)
{
	if(x > y || x < 0 || y >= strlen(s))
		return;
    int slen = y - x + 1;
    for(int i = 0; i < slen / 2; i++)
    {
        char temp = s[x + i];
        s[x + i] = s[x + slen - 1 - i];
        s[x + slen - 1 - i] = temp;
    }
}

char * reverseWords(char * s){
    reverse(s, 0, strlen(s) - 1);
    int head = 0, tail = strlen(s) - 1;
    while(head <= tail && s[head] == ' ')
        head++;
    while(head <= tail && s[tail] == ' ')
        tail--;
    if(head > tail)
        return "";

    int l;
    for(int i = head; i <= tail; i++)
    {
        while(i != tail + 1 && s[i] == ' ')
            i++;
        l = i;
        while(i != tail + 1 && s[i] != ' ')
            i++;
        reverse(s, l, i - 1);
    }

    l = 0;
    for(int i = head; i <= tail ; i++)
    {
        if(i != tail && s[i] == ' ' && s[i + 1] == ' ')
            continue;
        s[l++] = s[i];
    }
    s[l] = '\0';

    return s;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值