test1:反转字母
给你一个字符串
s
,根据下述规则反转字符串:
- 所有非英文字母保留在原有位置。
- 所有英文字母(小写或大写)位置反转。
返回反转后的
s
。示例 1:
输入:s = "ab-cd" 输出:"dc-ba"示例 2:
输入:s = "a-bC-dEf-ghIj" 输出:"j-Ih-gfE-dCba"示例 3:
输入:s = "Test1ng-Leet=code-Q!" 输出:"Qedo1ct-eeLg=ntse-T!"提示
1 <= s.length <= 100
s
仅由 ASCII 值在范围[33, 122]
的字符组成s
不含'\"'
或'\\'
void swap(char* c1, char* c2)
{char c = *c1;*c1 = *c2;*c2 = c;
}bool isLetter(char c)
{if ('a' <= c && c <= 'z')return true;if ('A' <= c && c <= 'Z')return true;return false;
}class Solution {
public:string reverseOnlyLetters(string s) {int begin = 0, end = s.size() - 1;while (begin < end){while (!isLetter(s[begin]) && begin < end)从左遍历字符串遇到直到字母,
//begin<end为了防止"#¥%&*¥#@"该字符串没有字母,循环不能终止,直至越界访问{begin++;}while (!isLetter(s[end]) && begin < end){end--;}swap(s[begin], s[end]);begin++;end--;}return s;}
};
test2:字符串中第一个唯一出现字符
给定一个字符串
s
,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回-1
。示例 1:
输入: s = "leetcode" 输出: 0示例 2:
输入: s = "loveleetcode" 输出: 2示例 3:
输入: s = "aabb" 输出: -1提示:
1 <= s.length <= 105
s
只包含小写字母
class Solution {
public:int firstUniqChar(string s) {int count[27] = { 0 };for (auto ch: s){count[ch - 'a']++;//统计各字符出现的次数,'a'- 'a' = 0,'b'- 'a'= 1,'c'- 'a'= 2...将字母映射到下标}for (int i = 0; i < s.size(); i++){if (count[s[i] - 'a'] == 1)//检查每个字符出现的次数是否为1,是则返回下标{return i;}}return -1;}
};
test3:最后一个单词的长度
描述
计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾)
输入描述:
输入一行,代表要计算的字符串,非空,长度小于5000。
输出描述:
输出一个整数,表示输入字符串最后一个单词的长度。
#include<iostream>
#include<string>
using namespace std;int lastwordcounts(string& s)
{string::reverse_iterator rit = s.rbegin();int count = 0;while (rit != s.rend())//遍历字符串{if (*rit == ' ')//遇到空格结束{break;}count++;rit++;}return count;
}int main()
{string s;getline(cin,s);//不能使用cin进行输入,cin遇到‘ ’停止读取cout << lastwordcounts(s) << endl;return 0;
}
test4:验证一个字符串是否是回文
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串
s
,如果它是 回文串 ,返回true
;否则,返回false
。
bool isPalindrome(string s)
{//保留字母,并将大写字母转换为小写string temp;for (auto ch : s){if (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ('0' <= ch && ch <= '9')){if ('A' <= ch && ch <= 'Z'){ch += 32;}temp += ch;}}int left = 0, right = temp.size() - 1;int flag = 1;while (left < right){if(temp[left] == temp[right]){left++;right--;}else{return false;}}return true;
}
test5:字符串相加
给定两个字符串形式的非负整数
num1
和num2
,计算它们的和并同样以字符串形式返回。你不能使用任何內建的用于处理大整数的库(比如
BigInteger
), 也不能直接将输入的字符串转换为整数形式。示例 1:
输入:num1 = "11", num2 = "123" 输出:"134"示例 2:
输入:num1 = "456", num2 = "77" 输出:"533"示例 3:
输入:num1 = "0", num2 = "0" 输出:"0"提示:
1 <= num1.length, num2.length <= 104
num1
和num2
都只包含数字0-9
num1
和num2
都不包含任何前导零
#include<iostream>
#include<string>
using namespace std;class Solution {
public:string addStrings(string num1, string num2) {string s;int end1 = num1.size() - 1;//最后一个有效字符的位置int end2 = num2.size() - 1;int next = 0;//进位int n = 0;//有效数字while (end1 >= 0 || end2 >= 0)//从最后一个有效字符的位置遍历字符串,直到两个字符串都结束{//0 1 1// 1 2 3int n1 = end1 >= 0 ? num1[end1] - '0' : 0;//分为该位置有无字符,如果有字符将其分别转化为数字存储在n1,和n2中,如果没有就把0存储在n1或n2中参与计算int n2 = end2 >= 0 ? num2[end2] - '0' : 0;n = (n1 + n2 + next) % 10;//(n1+n2+进位)取余 为有效数字 next = (n1 + n2 + next) / 10; //进位s.insert(s.begin(), n + '0'); //将有效数字存储转化为字符存储在string中end1--;end2--;}if (next == 1)//还存在进位{s.insert(s.begin(), '1');}return s;}
};int main()
{Solution sl;string s1("11");string s2("123");string s = sl.addStrings(s1, s2);cout << s;return 0;
}
test6: 翻转字符串2:翻转字符串中的单词
给定一个字符串
s
和一个整数k
,从字符串开头算起,每计数至2k
个字符,就反转这2k
字符中的前k
个字符。
- 如果剩余字符少于
k
个,则将剩余字符全部反转。- 如果剩余字符小于
2k
但大于或等于k
个,则反转前k
个字符,其余字符保持原样。
#include<iostream>
#include<string>
#include<stdbool.h>
using namespace std;int min(int a, int b)
{if (a > b){return b;}return a;
}string reverseStr(string s, int k)
{for (int i = 0; i < s.size(); i += (k * 2)){reverse(s.begin() + i, s.begin() + min(i + k, s.size()));//翻转每个下标从2k的倍数开始的,长度为k的子串,如果该子串长度不足k,则翻转整个子串}return s;
}int main()
{string s("abcdefg");int k = 2;cout << reverseStr(s, k) <<endl;return 0;
}
test7: 翻转字符串3:翻转字符串中的单词
给定一个字符串
s
,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
class Solution {
public:string reverseWords(string s){int begin = 0;int end;for (int i = 0; i < s.size(); i++)//遍历s{if (s[i] == ' ')//找到空格{end = i;reverse(s.begin() + begin, s.begin() + end);//翻转单词begin = end + 1;}}reverse(s.begin() + begin, s.end());//最后一个单词找不到空格,单独处理return s;}
};
test8: 字符串相乘
给定两个以字符串形式表示的非负整数
num1
和num2
,返回num1
和num2
的乘积,它们的乘积也表示为字符串形式。注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
class Solution {
public:string addStrings(string num1, string num2) {string s;int end1 = num1.size() - 1;//最后一个有效字符的位置int end2 = num2.size() - 1;int next = 0;//进位int n = 0;//有效数字while (end1 >= 0 || end2 >= 0)//从最后一个有效字符的位置遍历字符串,直到两个字符串都结束{//0 1 1// 1 2 3int n1 = end1 >= 0 ? num1[end1] - '0' : 0;//分为该位置有无字符,如果有字符将其分别转化为数字存储在n1,和n2中,如果没有就把0存储在n1或n2中参与计算int n2 = end2 >= 0 ? num2[end2] - '0' : 0;n = (n1 + n2 + next) % 10;//(n1+n2+进位)取余 为有效数字 next = (n1 + n2 + next) / 10; //进位s.insert(s.begin(), n + '0'); //将有效数字存储转化为字符存储在string中end1--;end2--;}if (next == 1)//还存在进位{s.insert(s.begin(), '1');}return s;}string multiply(string num1, string num2) {//1 2 3 4 n-1 n-1 n-1// i i i//1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 // 5 6 7 7 6 5 // 0 0 0 string ans;if (num1 == "0" || num2 == "0"){ans += "0";return ans;}int m = num1.size(), n = num2.size();int add = 0;//进位string curr;for (int i = n - 1; i >= 0; i--)//遍历mu2{curr.clear();for (int j = n - 1; j > i; j--)//将(i,n-1]之间补上字符0{curr += "0";}int y = num2[i] - '0';//将num2[i]变为数字0for (int j = m - 1; j >= 0; j--)//将num2的每个数字分别与num1相乘{int x = num1[j] - '0';int z = x * y + add;curr.push_back(z % 10 + '0');//(x+y+进位)取余 为有效数字 add = z / 10;//进位}if (add != 0)//还存在进位{curr.push_back(add % 10 + '0');add = add / 10;}reverse(curr.begin(), curr.end());//逆转每一次相乘结果ans = addStrings(ans, curr);//与最终结果相加}return ans;}
};