HJ1 字符串最后一个单词的长度
字符串最后一个单词的长度_牛客题霸_牛客网
这里可以使用rfind(),rfind()函数从字符串的末尾向前查找第一个空格的位置。这个空格将是最后一个单词和前面的单词的分隔符。首先使用getline读取字符串,然后用rfind找到最后一个空格的位置,最后根据找到的位置,计算最后一个单词的长度并输出。getline 的作用是从标准输入(cin)中读取一行文本,并将其存储到 word 字符串中。getline 读取操作在遇到换行符(\n)时结束,但换行符本身不会被存储到 word 中
代码:C++
#include <iostream>
using namespace std;
int main() {
string str;
// cin>>str;
getline(cin,str);
size_t pos = str.rfind(' ');
// size是最后一个字符的下一个位置
// cin输入多个字符串的时候是空格或者换行来间隔的
// 输入的这一行里面本身就有空格,cin就会认为这个空格是多个值之间的分割
// 比如hello nowcoder,cin里面就只有hello,nowcoder在缓冲区
if(pos != string::npos)
{
cout<<str.size()-pos-1<<endl;
}
// 如果找不到空格,那长度就是size
else
{
cout<<str.size()<<endl;
}
return 0;
}
541. 反转字符串 II
541. 反转字符串 II - 力扣(LeetCode)
- 我们以 2k为一个处理单位,每次对前 k个字符进行反转。具体操作就是每次从第i个字符开始,找到前 k个字符的位置,然后反转这部分字符串。
- 然后跳过下一个k个字符,继续处理下一个2k段。
下面是几个例子:
代码:C++
class Solution {
public:
string reverseStr(string s, int k)
{
int n = s.size();
// 每次都是2k个2k个进行处理,所以+=2k
for(int i=0; i<n; i += 2*k)
{
// reverse(s.begin() + i, s.begin() + min(i+k,n));
// 每隔2k个字符的前k个字符进行反转
// 剩余字符小于2k个但大于等于k个,则反转前k个字符
if(i + k <= s.size())
{
reverse(s.begin() + i, s.begin() + i + k);
continue;
}
// 剩余字符少于k个,则将剩余字符串全部反转
reverse(s.begin() + i, s.begin() + s.size());
}
return s;
}
};
557. 反转字符串中的单词 III
557. 反转字符串中的单词 III - 力扣(LeetCode)
解法一:双指针
使用一个 while 循环遍历整个字符串,直到 left 超过字符串长度。
在内部,使用另一个 while 循环找到当前单词的右边界,即找到下一个空格或者字符串的结尾
-
遍历字符串:
- 使用两个指针
left
和right
来标记每个单词的起始和结束位置。 - 从头到尾扫描字符串,当遇到空格或字符串末尾时,确定当前单词的范围。
- 使用两个指针
-
反转每个单词:
- 每找到一个完整的单词时(即从
left
到right
之间的字符),使用 C++ STL 的reverse
函数对该部分字符进行反转。
- 每找到一个完整的单词时(即从
-
跳过空格:
- 反转完成后,将
left
更新到下一个单词的起始位置,即跳过当前的空格。
- 反转完成后,将
-
处理边界条件:
- 当遍历到字符串末尾时停止,保证最后一个单词能正确处理,不遗漏任何字符。
代码:C++
class Solution {
public:
string reverseWords(string s) {
int left = 0;
int n = s.size();
while(left < n)
{
// 找到单词右边界
int right = left;
while(right < n && s[right] != ' ')
{
right++;
}
// 反转
reverse(s.begin() + left, s.begin() + right);
// 移动left到下一个单词的开头
left = right + 1;
}
return s;
}
};
125. 验证回文串
125. 验证回文串 - 力扣(LeetCode)
解法一:双指针
-
忽略非字母数字字符:
- 只需要关心字符串中的字母和数字字符,其余的字符(如标点符号、空格等)可以忽略。因此,需要一个辅助函数
isLetterOrNumber()
来判断当前字符是否是字母或数字。
- 只需要关心字符串中的字母和数字字符,其余的字符(如标点符号、空格等)可以忽略。因此,需要一个辅助函数
-
忽略大小写:
- 不区分大小写的方式是将所有大写字母转换为小写字母。可以通过 ASCII 码的转换来实现(大写字母的 ASCII 值比小写字母小 32)。
-
双指针法:
- 可以用两个指针,一个从字符串的头部(
begin
)开始,另一个从尾部(end
)开始,向中间移动,逐个字符进行比较。 - 每次循环中:
- 如果
begin
指针指向的字符不是字母或数字,则跳过该字符,继续向右移动。 - 如果
end
指针指向的字符不是字母或数字,则跳过该字符,继续向左移动。 - 如果
begin
和end
指针指向的字符都合法,比较它们是否相同。如果不相同,则返回false
,表示字符串不是回文。 - 如果字符相同,则继续移动指针,直到
begin >= end
,表示所有字符都匹配,则字符串是回文。
- 如果
- 可以用两个指针,一个从字符串的头部(
-
结束条件:
- 当
begin
和end
指针相遇或交错时,意味着所有字符已经比较完毕,如果没有发现不相同的字符,则可以判定字符串是回文。
- 当
代码:C++
class Solution {
public:
// 判断是不是字母和数字
bool isLetterOrNumber(char ch)
{
return (ch >= '0' && ch <= '9')
|| (ch >= 'a' && ch <= 'z');
}
bool isPalindrome(string s) {
// 加了引用,所以可以把大写字符转小写
for(auto& ch : s)
{
if(ch >= 'A' && ch <= 'Z')
{
ch += 32; // ASCII中,大写字母+32就是对应的小写字母
}
}
int begin = 0, end = s.size()-1;
while(begin < end)
{
while(begin < end && !isLetterOrNumber(s[begin])) // 如果是字母数字就停下来
{
// 如果不是字母数字就跳过
++begin;
}
while(begin < end && !isLetterOrNumber(s[end])) // 如果是字母数字就停下来
{
// 如果不是字母数字就跳过
--end;
}
if(s[begin] == s[end])
{
// 相等就继续比较
++begin;
--end;
}
else
{
return false;
}
}
return true;
}
};