[每日算法] leetcode第151题 Reverse Words in a String

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/csm201314/article/details/82819571

原题目描述

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

Example:

Input: “the sky is blue”,
Output: “blue is sky the”.

Note:

A word is defined as a sequence of non-space characters. Input string may contain leading or trailing spaces. However, your reversed string should not contain leading or trailing spaces. You need to reduce multiple spaces between two words to a single space in the reversed string.

Follow up: For C programmers, try to solve it in-place in O(1) space.

题目大意

题目意思,很简单,就是把一个字符串中的单词的顺序颠倒过来,其实是相当容易实现的一个问题,采用暴力求解的话,我们可以将该字符串中的每一个单词都拿出来,再做一个逆序排序输出就行了,但是这样实现不够优雅,上面化粗体的"Follow up"要求我们在O(1)的空间复杂度下实现代码,这就规定我们不能使用暴力求解了,因为你需要拿出来,就需要有空间存放,这时的空间复杂度为O(n)。

解题思路

因为要求在O(1)的空间复杂度下实现该题代码,则说明我们可以使用固定的额外空间就实现字符的逆序,其实这个问题可以简化为以下问题:
假设A,B分别是两个字符串,他们以AB的形式构成一个新的字符串,然后我们希望在O(1)的空间复杂度下把他变成BA的形式,应该如何去处理。
关于上面这个问题,我们可以很容易想到字符串的翻转,因为翻转的空间度杂度为O(1),我们只需要一个额外的空间,便可以实现将整个字符串进行翻转。
所以,首先,我们想到的是先把AB翻转一下,得到B’A‘,这里的B’和A‘分别是B和A翻转得到的字符串,这也很容易看出来,由翻转的镜像性。
到这里,你应该也可以很清楚地看出来,我们现在得到了B’A‘,然后目标字符串是BA,很明显,只需要将B’和A‘分别进行一次翻转就可以了。
所以一共经过3次翻转就解决了问题,而字符串的翻转的空间复杂度为O(1)。
然后回到原题,我们可以把原题现在的句子中的word看成我们上题的A和B对待,忽略空格,我们的句子其实就是ABC…,翻转一下便得到…C’B’A’。再依次将每一个word进行翻转便得到了逆序word的句子,这样我们只需要进行n+1次翻转(n为字符串中word的数量),而无论多少次翻转,我们的空间复杂度都为O(1)。

C++代码实现

class Solution {
public:
  void reverseWords(string &s) {
  	// 除去句子中多余空格
  	for (int i = 0; s[i] != 0; i++) {
  		if ((i == 0 && s[i] == ' ') || (s[i] == ' ' && (s[i+1] == ' ' || s[i+1] == 0))) {
  			s.erase(i, 1);
  			i--;
  		}
  	}
  	int len = s.size();

	// 整个字符串翻转
  	for (int i = 0; i < len/2; i++) {
  		swap(s[i], s[len-i-1]);
  	}

	// 对每个word进行翻转
  	int index = 0;
  	for (int i = 0; i <= len; i++) {
  		if (s[i] == ' ' || s[i] == 0) {
  			for (int j = index; j < (i+index)/2; j++) {
  				swap(s[j], s[i-(j-index)-1]);
  			}
  			index = i+1;
  		}
  	}

  }
};

猜你喜欢

转载自blog.csdn.net/csm201314/article/details/82819571
今日推荐