【LeetCode】Reverse Words in a String 三种解法

本文介绍了一种将输入字符串中的单词逆序输出的算法,并提供了三种实现方法,包括使用stringstream和栈、基本逻辑判断及O(1)空间复杂度的解决方案。

Given an input string, reverse the string word by word.

For example,
Given s = "the sky is blue",
return "blue is sky the".

click to show clarification.

Clarification:

  • What constitutes a word?
    A sequence of non-space characters constitutes a word.
  • Could the input string contain leading or trailing spaces?
    Yes. However, your reversed string should not contain leading or trailing spaces.
  • How about multiple spaces between two words?
    Reduce them to a single space in the reversed string.

我觉得本题有以下几个关键点:

1、单词在原句子中的位置倒序,但是单词内的字母不倒序;

2、题目对空格有相对严格的要求,输出句子的句首和句尾都不能有空格,多个空格变为一个空格,需谨慎处理。


方法一:stringstream输入流会从第一个非空白字符开始读入,直到下一个空白字符为止,利用stringstream输入流每次读入的都是符合要求的单词,自然地处理好空格问题,然后依次将读入的单词压入栈中,再从栈中取出,很好地解决了关键点1的问题。

空间复杂度为:O(N);

时间复杂度为:O(N);

class Solution {
public:
    void reverseWords(string &s) {
    stack<string> sstk;
		string st;
		stringstream ss(s);
		while (ss >> st)
		{
			sstk.push(st);
		}
		st = "";
		while (!sstk.empty())
		{
			if (!st.empty())
				st.push_back(' ');
			st += sstk.top();
			sstk.pop();
		}
		s = st;
    }
};

方法二:不使用栈,运用最基本的逻辑判断来解决空白字符和单词、字母顺序问题。

class Solution {
public:
    void reverseWords(string &s) {
    	int size=s.size();
    	//如果s为空字符串,返回。
	if(size==0)
	    return;
	string st;
	int flag=0;
	//如果s为一串空格,令s="",返回。
	while(flag<size && isspace(s[flag]))
		flag++;
	if(flag==size)
	    {
	        s="";
	        return;
	    }
	//用flag标记第一个单词的末尾下标,供下面检验。
	while(flag+1<size && !isspace(s[flag+1]))
		flag++;
	//正常情况下,有多个单词的处理方法,
	for(int i=size-1,j=size-1;i>=0;i=j)
	{
		while(i>=0 && isspace(s[i]))
			i--;
		j=i;
		while(j>=0 && !isspace(s[j]))
			j--;
		for(int k=j+1;k<=i;k++)
			st+=s[k];
		if(i!=flag && i>=0)
			st+=" ";
	}
	s=st;
        
    }
};

方法三:O(1)空间复杂度,O(N)时间复杂度的方法。通过增加代码复杂性降低空间复杂度。思路如下:

1、去除s中最前、最后的空格,如果s中只有空格,返回“”;

2、翻转s中的字符;

3、依次找到翻转后的s中的单词边界(空格),翻转该空格前一个单词中的字符,通过while循环删除多余的空格,保证输出s中各单词间隔仅有一个空格。

class Solution {
public:
    void swap(char *s, int i, int j){
		char t = s[i];
		s[i] = s[j];
		s[j] = t;
	}

	void reverse_string(char * s, int length){
		for (int i = 0; i<length / 2; i++){
			swap(s, i, length - i - 1);
		}
	}
	void removeSpaceInTwoSides(string &s)
	{
		string::iterator iter = s.begin();
		while (iter != s.end())
		{
			if (isspace(*iter))
				s.erase(iter);
			else
				break;
		}
		if (s.empty())
		{
			return;
		}
		iter = s.end() - 1;
		while (isspace(*iter))
			s.erase(iter--);
	}
    void reverseWords(string &s) {
        removeSpaceInTwoSides(s);

		int size = s.size() ;
		//Reverse string
		reverse_string(&s[0], size );
		int p = 0;
		//Find word boundaries and reverse word by word
		for (int i = 0; i<s.size(); i++){
			if (s[i] == ' '){
				//string & stmp = s[p];
				reverse_string(&s[p], i - p);
				p = i + 1;
			}
			while (s[i] == ' ' && s[i+1] == ' ')
				s.erase(i, 1);
		}
		//Finally reverse the last word.
		reverse_string(&s[p], s.size() - p);
    }
};








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值