前言:
🎯个人博客:Dream_Chaser
🎈博客专栏:C++
📚本篇内容:仅仅反转字母、字符串中的第一个唯一字母、字符串最后一个单词的长度、验证回文串、字符串相加
目录
917.仅仅反转字母
题目描述:
387.字符串中的第一个唯一字符
题目描述:
HJ1 字符串最后一个单词的长度
输入描述:
输出描述:
125.验证回文串
题目描述:
415.字符串相加
题目描述:
917.仅仅反转字母
题目链接:917. 仅仅反转字母 - 力扣(LeetCode)
题目描述:
给你一个字符串 s
,根据下述规则反转字符串:
- 所有非英文字母保留在原有位置。
- 所有英文字母(小写或大写)位置反转。
返回反转后的 s
。
题目示例:
题目思路:
使用begin和end两个指针,开始时begin指向字符串开头,end指针指向字符串末尾(’\0’的前一个字符)。当两指针同时指向字母时,应该立即进行交换,接着begin++,end--。若其中一个遇到非字母或者两个指针同时遇到非字母,则跳过该字符,进行对应的++,-- 操作,重复上述步骤。当begin>end循环结束,返回 s .
起始图:
动态过程:
结果图:
代码:
class Solution {
public:
bool isLetter(char ch)
{
if(ch>= 'A' && ch<='Z')
return true;
if(ch>='a' && ch<='z')
return true;
return false;
}
string reverseOnlyLetters(string s) {
int begin = 0,end=s.size()-1;
while(begin<end)
{
//先写出判断条件,避免越界问题,再判断是否为字母
//遇到非字母跳过
while(begin<end && !isLetter(s[begin]))
{
++begin;
}
while(begin<end && !isLetter(s[end]))
{
--end;
}
//进行字母间的交换
swap(s[begin],s[end]);
++begin;
--end;
}
return s;
}
};
387.字符串中的第一个唯一字符
题目链接:387. 字符串中的第一个唯一字符 - 力扣(LeetCode)
题目描述:
给定一个字符串 s
,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1
。
示例:
思路:
使用一个大小为26个int的数组countA(因为只有26个字母)统计字符串 s 中每个字母出现的次数,然后再遍历一次字符串,找到第一个唯一字符(字符串中只有这一个只出现一次,并且它是第一个,即使后面有唯一字符,也是返回第一个出现的字符),返回它在该字符串 s 中的索引,若找不到则返回-1。
class Solution {
public:
int firstUniqChar(string s) {
//计算这个字符串某个字符出现次数的数组
int countA[26] = {0};
//范围for统计出字符串中每个元素出现的次数
for(auto ch : s)
{
countA[ch - 'a']++;//映射其在字母表中的位置
}
for(int i =0;i<s.size();i++)
{
if(countA[s[i] - 'a'] == 1)//找到s中第一次出现的字母
{
return i;//返回其索引
}
}
return -1;//找不到
}
};
HJ1 字符串最后一个单词的长度
题目链接:字符串最后一个单词的长度_牛客题霸_牛客网 (nowcoder.com)
题目描述:
计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾)
输入描述:
输入一行,代表要计算的字符串,非空,长度小于5000。
输出描述:
输出一个整数,表示输入字符串最后一个单词的长度。
示例:
图解:
#include <iostream>
using namespace std;
#include<string>
int main()
{
string str;
getline(cin,str);//不要使用cin>>line,因为会它遇到空格就结束了
size_t i =str.rfind(' ');//找到此字符串的最后一个空格的位置
if(i != string::npos)//等于则表示“未找到”或者“超出范围”
{
cout<<str.size() - (i+1)<<endl;
}
else//字符串没有空格,则计算整个字符串的大小
{
cout<<str.size()<<endl;
}
}
125.验证回文串
题目链接:125. 验证回文串 - 力扣(LeetCode)
题目描述:
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s
,如果它是 回文串 ,返回 true
;否则,返回 false
。
题目示例:
解题思路:
先写一个判断是否为字母和数字的函数,然后写一个判断回文数的函数,先用范围for遍历这个字符串,将所有小写字母变成大写字母(为什么不用大写转小写呢?)看下面解释:
将所有小写字母转换成大写后,此时定义begin指向字符串的开头,end则指向字符串结尾('\0'的前一个位置),循环条件是begin < end,此时遍历字符串,begin向右移动,end向左移动,如果遇到 空格,以及其他非数字非字母的字符则直接跳过。
之后,如果两指针此时指向的字符不一样(因为前面已经小写转大写)则直接返回false,如果相同依旧是begin++,end--,当遍历完字符串时,则说明此字符串为回文字符串,返回true。
代码:
class Solution {
public:
//判断是否是字母,数字,是返回true,否则为false
bool isLetterOrNumber(char ch)
{
return (ch>='0' && ch<='9')
|| (ch>='a' && ch<='z')
|| (ch>='A' && ch<='Z');
}
//确保在后续比较时,无论是大写还是小写字母,都被视为相同的字符
//这样做的好处在于,当判断字符串是否为回文串时,我们不需要区分大小写
//在忽略空格并统一字母大小写后,其回文性更容易判断
bool isPalindrome(string s)//判断是否是回文数
{
for(auto&ch :s){
if(ch>='a' && ch<= 'z')
{
ch -= 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])
{
return false;
}
else
{
++begin;
--end;
}
}
return true;
}
};
415.字符串相加
题目链接:415. 字符串相加 - 力扣(LeetCode)
题目描述:
给定两个字符串形式的非负整数 num1
和num2
,计算它们的和并同样以字符串形式返回。
你不能使用任何內建的用于处理大整数的库(比如 BigInteger
), 也不能直接将输入的字符串转换为整数形式。
题目示例:
代码:
class Solution {
public:
string addStrings(string num1, string num2) {
int end1=num1.size()-1,end2=num2.size()-1;
string str;
//进位
int next= 0;
while(end1>= 0 || end2>=0)
{
int x1 = end1 >=0 ? num1[end1]-'0' : 0;
int x2 = end2 >=0 ? num2[end2] -'0': 0;
int ret = x1 + x2 +next;
//进位
next = ret/10;
ret= ret%10;
//头插
str.insert(0,1,'0'+ret);
--end1;
--end2;
}
if(next ==1)
str.insert(0,1,'1');
return str;
}
};
本篇完。
🔧本文修改次数:0
🧭更新时间:2024年4月7日