力扣58:最后一个有效单词的长度
问题
给你一个字符串 s,由若干单词组成,单词之间用空格隔开。返回字符串中最后一个单词的长度。如果不存在最后一个单词,请返回 0 。
单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。
示例
输入:s = “hello world”
输出:5
输入:s = " "
输出 : 0
输入:s = "a b "
输出: 1
输入:s = “a”
输出:1
代码
class Solution {
public:
int lengthOfLastWord(string s) {
int res = 0, len = s.size() - 1;
while(len >= 0 && s[len] == ' ')
{
len --;
}
while(len >= 0 && s[len --] != ' ')
{
res ++;
}
return res;
}
};
力扣151:翻转字符串里的单词
给定一个字符串,逐个翻转字符串中的每个单词。
说明:
- 无空格字符构成一个 单词 。
- 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
- 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
本解法在求取最后一个有效单词长度的基础上进行改进,大致思路:
- 确定当前字符串的最后一个单词,提取出来放到结果中,补充空格
- 重复第一步步骤,直到从初始字符串尾部到头部,遍历完成。
class Solution {
public:
string reverseWords(string s) {
string res;
int i = s.size() - 1;
while(i>= 0)
{
int j = 0;
while(i >= 0 && s[i] == ' ') i--;
while(i >= 0 && s[i] != ' ')
{
i--;
j++;
}
//提取最后一个单词
if(j)
{
res += s.substr(i+1,j) ;
res += " ";
}
}
return res.substr(0,res.size()-1);
}
};
时间复杂度:
O
(
N
)
O(N)
O(N)
空间复杂度:
O
(
N
)
O(N)
O(N)
官方解法
官方解法是将字符串直接翻转,之后再翻转每一个单词。
class Solution {
public:
string reverseWords(string s) {
// 反转整个字符串
reverse(s.begin(), s.end());
int n = s.size();
int idx = 0;
for (int start = 0; start < n; ++start) {
if (s[start] != ' ') {
// 填一个空白字符然后将idx移动到下一个单词的开头位置
if (idx != 0) s[idx++] = ' ';
// 循环遍历至单词的末尾
int end = start;
while (end < n && s[end] != ' ') s[idx++] = s[end++];
// 反转整个单词
reverse(s.begin() + idx - (end - start), s.begin() + idx);
// 更新start,去找下一个单词
start = end;
}
}
s.erase(s.begin() + idx, s.end());
return s;
}
};
时间复杂度:
O
(
N
)
O(N)
O(N)
空间复杂度:
O
(
1
)
O(1)
O(1)
力扣344:反转字符串
解题思路
1.最简单的方法是利用现有函数reverse(s.begin(),s.end())直接反转,太香了。
2.第二种方法是头尾指针交换,遍历一次即可,空间复杂度为O(1)。
class Solution {
public:
void reverseString(vector<char>& s) {
//reverse(s.begin(),s.end());
int head = 0, tail = s.size() - 1 ;
char c ;
while(head < tail)
{
c = s.at(tail);
s.at(tail) = s.at(head);
s.at(head) = c;
head ++;
tail --;
}
}
};