本文是(第21讲) 字符串算法(一) - 字符串遍历所涉及课后习题的解答,发帖来记录自己关于这些题的理解和做题过程中思路,如果有错误,欢迎批评指正。
1.判断国际棋盘中格子的颜色
题目:给你一个坐标 coordinates,它是一个字符串,表示国际象棋棋盘中一个格子的坐标。若坐标代表的颜色为白色,则返回true,否则返回false。
主要思路:找规律,将横纵坐标转换为1-8,比如,当输入“a1”时,可将其转化为“(1,1)”,然后,可以发现,对于奇数列,当行为偶数时,块为白色;对偶数列,当行为偶数时,块为黑色,据此可写出代码。
代码:
class Solution {
public:
bool squareIsWhite(string coordinates) {
int x=coordinates[0]-'a'+1,y=coordinates[1]-'1'+1;
return x%2? (y%2==0? true : false) :(y%2==0? false : true);
}
};
2.速算机器人
题目:给定x=1,y=0,然后输入由A和B组成的指令:
对A,x=2x+y;
对B,y=2y+x;
根据指令计算,并返回最终的x+y。
代码:
class Solution {
public:
int calculate(string s) {
int x=1,y=0;
for(auto ch : s){
if(x=='A'){
x=2*x+y;
}else{
y=2*y+x;
}
}
return x+y;
}
};
3.执行操作后的变量值
题目:给定初值x=0,输入字符串,其中包含:"++X"、“X++”、"–X"、“X–”,根据字符数组中的操作,对x进行相应的自增自减操作,返回最终的结果。
代码:
class Solution {
public:
int finalValueAfterOperations(vector<string>& operations) {
int x=0;
for(auto s:operations){
if(s=="++X" || s=="X++"){
x++;
}else{
x--;
}
}
return x;
}
};
4.长度为3且各字符不同的子数组
题目:如果一个字符串不含有任何重复字符,我们称这个字符串为 好 字符串。给你一个字符串 s ,请你返回 s 中长度为 3 的 好子字符串 的数量。
注意,如果相同的好子字符串出现多次,每一次都应该被记入答案之中。
主要思路:一次遍历,不断判断以当前字符为首的三个字符子串是否包含重复字符,若不包含,则计数变量ans加一。
代码:
class Solution {
public:
int countGoodSubstrings(string s) {
int ans=0;
if(s.size()<3){
return 0;
}
for(int i=0;i<s.size()-2;i++){
if(s[i]!=s[i+1] && s[i]!=s[i+2] && s[i+1]!=s[i+2]){
ans++;
}
}
return ans;
}
};
5.检测大写字母
题目:我们定义,在以下情况时,单词的大写用法是正确的:全部字母都是大写,比如 “USA” 。单词中所有字母都不是大写,比如 “leetcode” 。如果单词不只含有一个字母,只有首字母大写, 比如 “Google” 。给你一个字符串 word ,判断其中的单词大写用法是否正确。
主要思路:若对于字符串,所有字符都是大写或从第二个字符开始都是小写,则返回true。
代码:
class Solution {
public:
bool detectCapitalUse(string word) {
bool allUpper=true,lowerAfterFirst=true;
for(int i=0;i<word.size();i++){
if(word[i]>='a' && word[i]<='z'){
allUpper=false;
}
}
for(int i=1;i<word.size();i++){
if(word[i]>='A' && word[i]<='Z'){
lowerAfterFirst=false;
}
}
return allUpper||lowerAfterFirst;
}
};
6.转换为小写字母
题目:给定一个字符数组,将其中的所有大写字母转换为小写字母。
代码:
class Solution {
public:
string toLowerCase(string s) {
string ans;
for(auto ch:s){
if(ch>='A' && ch<='Z'){
ch=ch-'A'+'a';
}
ans+=ch;
}
return ans;
}
};
7.判断字符串中的两半是否相等
题目:给定一个字符数组,长度为偶数,判断其前半部分和后半部分中是否含有相同数量的元音字母(aeiouAEIOU)。
代码:
class Solution {
public:
bool halvesAreAlike(string s) {
string s1=s.substr(0,s.size()/2);
string s2=s.substr(s.size()/2,s.size());
int l1=0,l2=0;
for(auto ch:s1){
if(ch=='a' || ch=='e' ||ch=='i' ||ch=='o' ||ch=='u' ||ch=='A' ||ch=='E' ||ch=='I' ||ch=='O' ||ch=='U')
{
l1++;
}
}
for(auto ch:s2){
if(ch=='a' || ch=='e' ||ch=='i' ||ch=='o' ||ch=='u' ||ch=='A' ||ch=='E' ||ch=='I' ||ch=='O' ||ch=='U')
{
l2++;
}
}
return l1==l2;
}
};
8.将所有数字用字符替换
题目:给你一个下标从 0 开始的字符串 s ,它的 偶数 下标处为小写英文字母,奇数 下标处为数字。定义一个函数 shift(c, x) ,其中 c 是一个字符且 x 是一个数字,函数返回字母表中 c 后面第 x 个字符。
例如,shift(‘a’, 5) = ‘f’ 和 shift(‘x’, 0) = ‘x’ 。
对于每个 奇数 下标 i ,你需要将数字 s[i] 用 shift(s[i-1], s[i]) 替换。请你替换所有数字以后,将字符串 s 返回。题目 保证 shift(s[i-1], s[i]) 不会超过 ‘z’ 。
代码:
class Solution {
public:
char shift(char c,int x){
char ans=c+x;
return ans;
}
string replaceDigits(string s) {
for(int i=1;i<s.size();i+=2){
s[i]=shift(s[i-1],s[i]-'0');
}
return s;
}
};
9.字符串中的不同整数数目
题目:给你一个字符串 word ,该字符串由数字和小写英文字母组成。
请你用空格替换每个不是数字的字符。例如,“a123bc34d8ef34” 将会变成 " 123 34 8 34" 。注意,剩下的这些整数为(相邻彼此至少有一个空格隔开):“123”、“34”、“8” 和 “34” 。
返回对 word 完成替换后形成的 不同 整数的数目。
只有当两个整数的 不含前导零 的十进制表示不同, 才认为这两个整数也不同。
主要思路:使用res变量存储遍历过程中的整数,从头开始遍历字符串,若当前字符不为数字,那么若res不为空,则此时res即为一个有效的整数,将它存入unordered_set中,并清空res。若当前字符为数字,则首先检测res是否为“0”,若是,则将res清空,因为该0为前导零,然后将当前字符存入res中。由于在遍历过程中,整数的判定是通过其后的非数字字符完成的,所以需要在开始时往word后加空格,防止出现数组以“整数字符”结尾时检测不到该整数的情况。最后,哈希集unordered_set的大小即为所求的不同整数的数目。
代码:
class Solution {
public:
int numDifferentIntegers(string word) {
word += ' ';
string res;
unordered_set<string> chart;
for (auto ch : word)
{
if (!isdigit(ch))
{
if(res!=""){
chart.insert(res);
res.clear();
}
}
else
{
if (res == "0") res.clear();
res += ch;
}
}
return chart.size();
}
};