面试题58 - I. 翻转单词顺序

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

输入: “the sky is blue”
输出: “blue is sky the”

示例 2:

输入: " hello world! "
输出: “world! hello”

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

输入: “a good example”
输出: “example good a”

解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

1.利用辅助空间数组 O(N)S(N)

这个思想很简单,就是利用数组先把每个单词保存下来,在从尾到头放到字符串中,注意两点就可以了:

  • 因为不能包含多余的空格,所以数组在保存单词是空格我们不进行保存,数组只存储单词
  • 在从尾到头放到字符串时加空格,注意0号下标单词不加空格。
string reverseWords(string s) 
{
	vector<string> tmp;
	string res="";
	for(int i=0;i<=s.size();i++)
	{
		if(s[i]==' '|| s[i]=='\0')
		{
			if(res!="")//处理多余的空格
				tmp.push_back(res);
			res="";
		}
		else
		{
			res+=s[i];
			continue;
		}
	}
	for(int i=tmp.size()-1;i>=0;i--)
	{
		res=res+tmp[i];
		if(i!=0)//为了防止末尾加空格
			res+=" ";	
	}
	return res;
}
int main()
{
	string s="The sky";
	cout<<reverseWords(s);
}

2.两次翻转字符串(麻烦)

建议如果需要处理空格的情况,用上面的比较好,好想一点,翻转字符串的话就需要处理太多了,主体思想就是先反转字符串,再反转每个单词。

  • 先写一个反转函数
  • 处理字符串,去掉前面的空格,后面的空格,单词之间的空格(快慢指针)
  • 字符串反转
  • 单词翻转。
string reverse(string s,int start,int end)//反转函数
{
	char temp;
	while(start<=end)
	{
		temp=s[start];
		s[start]=s[end];
		s[end]=temp;
		start++;
		end--;
	}
	return s;
}
string reverseWords(string s) 
{
	int start=0;
	int end=s.size()-1;
	string tmp="";
	s.erase(0, s.find_first_not_of(' '));// 去掉前面的空格
    s.erase(s.find_last_not_of(' ') + 1); // 去掉后面的空格
	int fast = 1, slow = 0;//删掉单词间的多余空格
	while (slow<s.length()) 
	{
        if (s[slow]==' '&& s[fast]==' ') // 当慢指针和快指针同时指向空字符时
		{
            // 如果有多于2的空字符,
            // 就将快指针继续后移,一直到不是空字符为止
            while (s[fast] == ' ') 
			{
                fast++;
            }
            // 因为此时fast指向非空字符,
            // 则删掉除slow指向的空字符外的其它空字符
            // 删掉的空字符数为: fast - slow - 1
            s.erase(slow, fast - slow - 1);
            // slow指向空格,fast继续指向slow后面
            fast = slow + 1;
        } else {
            slow++;
            fast++;
        }
    }
	end=s.size()-1;
	s=reverse(s,start,end);//翻转了整个字符串
	for(int i=0,j=0;i<=s.size(),j<=s.size();)
	{
		if(s[j]==' '||s[j]=='\0')
		{
			s=reverse(s,i,j-1);//饭庄单词
			i=j+1;
			j=i;
		}
		else
		{
			j++;
			continue;
		}

	}
	return s;
}

加油哦!💪。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值