跟着英雄哥打卡第二十五天
[专题跳转->《算法零基础100讲》]
[万人千题社区跳转]
跳转力扣:344. 反转字符串
难度:★☆☆☆☆
说明:基础的字符串翻转问题,双指针实现头尾交换,每交换一次向中间靠拢,直至两个指针相遇
代码如下(示例):
class Solution {
public:
void reverseString(vector<char>& s) {
for(int l = 0, r = s.size()-1; l < r ; l ++, r --){
swap(s[l], s[r]);
}
}
};
跳转力扣:2000. 反转单词前缀
难度:★☆☆☆☆
说明:使用字符串内置函数find()查找是否存在查找的字母,若未找到直接返回原字符串,若找到可用reverse函数实现从下标为0到下标为f之间的字符串翻转
代码如下(示例):
class Solution {
public:
string reversePrefix(string word, char ch) {
int f = word.find(ch);
if (f == -1) return word;
reverse(word.begin(), word.begin() + f + 1);
return word;
}
};
跳转力扣:345. 反转字符串中的元音字母
难度:★☆☆☆☆
说明:使用yy字符串存储元音字母以便在判断是否为元音字母的check()函数中遍历时使用,同样使用头尾双指针查找离两端最近的元音字母,并实现交换,直至两个指针相遇
代码如下(示例):
class Solution {
public:
string yy = "aeiouAEIOU";
bool check(char c) {
for (auto &y: yy) {
if (c == y) return true;
}
return false;
}
string reverseVowels(string s) {
int l = 0, r = s.size() - 1;
while (l < r) {
while (l < r && !check(s[l])) l ++;
while (l < r && !check(s[r])) r --;
if (l < r) {
swap(s[l], s[r]);
l ++, r --;
}
}
return s;
}
};
跳转力扣:剑指 Offer 58 - I. 翻转单词顺序
难度:★★☆☆☆
说明:先对空字符串"“做一个特判,后对头尾的空格进行删除,删除结束后若尾指针跑到头指针前面去了,说明该字符串为全空格字符串,直接返回空字符串”",否则截取从i到j之间的字符串作为我们将要研究的字符串,为方便判断可以在字符串头部加一个空格方便后续判断;
j指针记录当前从后往前遍历到的位置,i表示从后往前遍历到的单词的第一个字母的位置,若j遇到空格则表示该单词记录结束,用substr()函数截取子串,并加入到答案中;
特别注意:遍历时需要做跳过连续的空格的操作,并注意字符串越界致命问题
代码如下(示例):
class Solution {
public:
string reverseWords(string s) {
int i = 0, j = s.size() - 1;
if (s == "") return "";
while (i <= j && s[i] == ' ') i ++;
while (j >= 0 && s[j] == ' ') j --;
if (i > j) return "";
s = s.substr(i, j - i + 1);
s = " " + s;
string res, ans = "";
for (int j = s.size() - 1, i = s.size() - 1; j >= 0; j --) {
if (s[j] == ' '){
ans += s.substr(j + 1, i - j);
if (j != 0)
ans += ' ';
if (j > 0)
while (s[j-1] == ' ') j --;
i = j - 1;
}
}
return ans;
}
};
跳转力扣:151. 翻转字符串里的单词
难度:★★☆☆☆
说明:与上题相同
跳转力扣:557. 反转字符串中的单词 III
难度:★★☆☆☆
说明:手写myreverse函数实现字符串翻转,res维护单词,ans维护答案句子,同样在尾部加入空格字符为后续方便判断,遍历字符串若遇到空格,则将存储的字符串翻转后存入句子中,注意存入后续讲存储的单词清空后再进行下一次循环操作,每个单词后加入空格,除最后一个外,因此需要做一个特判
代码如下(示例):
class Solution {
public:
string myreverse(string s) {
for (int l = 0, r = s.size() - 1; l < r; l ++, r --) {
swap(s[l], s[r]);
}
return s;
}
string reverseWords(string s) {
s += ' ';
string res, ans;
for (int i = 0; i < s.size(); i ++) {
if (s[i] != ' ')
res += s[i];
else {
ans += myreverse(res);
if (i != s.size() - 1)
ans += ' ';
res = "";
}
}
return ans;
}
};
跳转力扣:541. 反转字符串 II
难度:★★☆☆☆
说明:手写myreverse函数实现字符串翻转,res维护单词,ans维护答案句子,此题最难处理的是越界问题,首先每一段2*k的区间判断需要翻转的前半部分是否超出字符串,若已超出则对前半部分剩余的进行翻转即可(不需要再将后半部分插入,会越界),若未超出需要将前半部分的字符串翻转加入ans中,并将后半部分的加入ans中
代码如下(示例):
class Solution {
public:
string myreverse(string s) {
for (int l = 0, r = s.size() - 1; l < r; l ++, r --) {
swap(s[l], s[r]);
}
return s;
}
string reverseStr(string s, int k) {
string res, ans;
for (int i = 0; i < s.size(); i += 2*k) {
if (i + k > s.size() - 1){
ans += myreverse(s.substr(i, k));
}
else {
ans += myreverse(s.substr(i, k));
ans += s.substr(i + k, k);
}
}
return ans;
}
};
跳转力扣:917. 仅仅反转字母
难度:★★☆☆☆
说明:头尾双指针,找到距离头尾两端最近的字母,用swap()函数交换,交换后两个指针向中间靠拢,循环操作直至两个指针相遇
代码如下(示例):
class Solution {
public:
string reverseOnlyLetters(string s) {
int l = 0, r = s.size() - 1;
while (l < r) {
while (l < r && !isalpha(s[l])) l ++;
while (l < r && !isalpha(s[r])) r --;
if (l < r) swap(s[l], s[r]);
l ++, r --;
}
return s;
}
};
跳转力扣:7. 整数反转
难度:★★☆☆☆
说明:由于有“如果反转后整数超过 32 位的有符号整数的范围 [−2^31, 2^31 − 1] ,就返回 0”的限制,需要每次左移的时候对目前数字判断是否超过整数的范围。
代码如下(示例):
class Solution {
public:
int reverse(int x) {
int rev = 0;
while(x != 0){
int pop = x % 10;
x /= 10;
if(rev > INT_MAX/10 || (rev == INT_MAX/10 && pop > 7)) return 0;
if(rev < INT_MIN/10 || (rev == INT_MIN/10 && pop < -8)) return 0;
rev = rev*10 + pop;
}
return rev;
}
};