leetcode151.翻转字符串里的单词

题目大意

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

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

解题思路

方法一:

首先用双指针的方式确定每个单词的始末位置,然后将这个子串放入数组中。最后将数组中的单词反向串联即可。

class Solution {
public:
    string reverseWords(string s) {
    	if (s.size() == 0)
    		return {}; 
    	vector<string> v;
    	string tmp;
    	int left = 0, right = 0;

    	while (left < s.size()){
    		// 找到当前单词的起始位置
    		while (left < s.size() && s[left] == ' ')
    			++left;
    		if(left == s.size())
    			break;
    		right = left;
    		// 找到当前单词的结束位置的后一个位置
    		while (right < s.size() && s[right] != ' '){
    			++right;
    		}
			// 将单词放入数组中
    		tmp = s.substr(left, right - left);
    		v.push_back(tmp);

    		left = right;
    	}
    	if (v.empty())
    		return {};
		// 拼接单词
    	string res = v.back();
    	for (int i = v.size() - 2; i>= 0; --i){
    		res = res + ' ' + v[i];
    	}
    	return res;
    }
};
方法二:

方法一使用了额外的数组,方法二中原地修改字符串。首先如同方法一,通过双指针找到字符串中的每个单词,然后将单词逆序。全部单词逆序后再将整个字符串逆序,这样单词顺序交换完毕。
剩下的工作就是排除字符串中多余的空格。

首先找到翻转后的字符串的第一个字母位置,利用双指针left(有效位置)和right(当前检索位置)去除空格。
如果s[right]是字母,则将s[left]s[right]交换,然后两个指针同时移动到下一个位置;
如果s[right] == ' ',此时如果s[left]的前一个位置不是' ',表明需要留一个空格,left向后移动一位;如果s[left]前一个位置是' ',表示不需要留有空格,left不移动。无论如何,right向后移动一位。(因为每个单词之间需要且只需要一个空格)

class Solution {
public:
    string reverseWords(string s) {
    	if (s.empty())
    		return {};

    	int left = 0, right = 0;
		// 逆转所有单词
    	while (left < s.size()){
    		while (left < s.size() && s[left] == ' ')
    			++left;
    		if (left == s.size())
    			break;

    		right = left;
    		while (right < s.size() && s[right] != ' ')
    			++right;

    		reverseSubString(s, left, right - 1);

    		left = right;
    	}
		// 逆转整个字符串
    	reverseSubString(s, 0, s.size() - 1);
		
		// 找到第一个位置
    	left = 0;
    	while (left < s.size() && s[left] == ' ')
    		++left;

    	int start = left;

    	right = left;
    	while (right < s.size()){
    		if (s[right] != ' '){
    			reverse(s[left++], s[right++]);
    		}
    		else{
    			// 如果是s[left-1]==' ',表明两个单词间已经有了一个空格,不需要再留一个空格了
    			if (s[left - 1] != ' ')
    				++left;
    			++right;
    		}
    	}
		// 上述操作结束后,left可能超出数组范围,也可能停留在最后一个空格上,因此从后往前找到left不为‘ ’的位置
    	for (left = s.size() - 1; left >= 0 && s[left] == ' '; --left);

    	return s.substr(s, start, left);
    }

    void reverseSubString(string & s, int left, int right){
    	while (left < right){
    		reverse(s[left++], s[right--]);
    	}
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值