代码随想录算法训练营第7天|344.反转字符串、541. 反转字符串II、替换数字、151.翻转字符串里的单词
LeetCode344
2025-01-28 17:39:48 星期二
题目描述:力扣344
文档讲解:代码随想录(programmercarl)344.反转字符串
视频讲解:《代码随想录》算法视频公开课:字符串基础操作! | LeetCode:344.反转字符串
代码随想录视频内容简记
本题仍然是使用双指针法进行解决,在头部设置一个指针,在尾部设置一个指针,然后两两交换,和206.反转链表的方式有不一样,不是两个指针都在头部,同时向尾部移动。和977.有序数组的平方,还有15.三数之和和18.四数之和的移动方式是一致的。
另外注意一点,就是关于交换两个元素的值。除了定义一个tmp变量进行交换,还可以使用异或运算。注意两数不同(0和1)异或得1,两数相同异或得0(0和0,或者1和1)
s[i] = s[i] ^ s[j];
s[j] = s[j] ^ s[i];
s[i] = s[i] ^ s[j];
这样的方式也可以完成两数的交换
梳理
-
注意要分类讨论一种情况,就是字符串的长度为奇数或者为偶数
-
如果为奇数,则最中间的一位仍然不用移动
-
如果为偶数,则正好可以两两交换
大致代码内容
- 只需设置一个循环
for (int i = 0, j = nums.size() - 1; i < nums.size() / 2; i++, j--)
- swap (nums[i], nums[j])
LeetCode测试
完整代码如下
点击查看代码
class Solution {
public:
void reverseString(vector<char>& s) {
for (int i = 0, j = s.size() - 1; i < s.size() / 2; i++, j--) {
swap(s[i], s[j]);
}
}
};
LeetCode541
题目描述:力扣541
文档讲解:代码随想录(programmercarl)541. 反转字符串II
视频讲解:《代码随想录》算法视频公开课:字符串操作进阶! | LeetCode:541. 反转字符串II
代码随想录视频简记
梳理

-
一个for循环,操作语句可以每次控制2k个距离,遍历至最后,剩余的字符串长度不够2k为止
-
每次对2k个字符串中前k个字符串进行反转
-
最后剩余的字符串如果足够k个长度,则反转前k个
-
剩余的字符串如果不够k个长度,则全部反转
大致代码内容
-
for (int i = 0; i < s.size(); i += 2k)
-
if (i + k <= s.size()) reverse(s, i, i + k)
,注意,无论是否遍历至剩余字符串,i + k
如果足够,那就必须要进行反转。至于这里为什么要加上=
,是因为如果s = "abc"
,k = 3
,无法遍历至2k
个,则按照题目要求,这三个字符串要全部进行反转。
这一步实现的就是“最后剩余的字符串如果足够k个长度,则反转前k个”,反转完成后剩余的字符串不够2k个,会直接成为剩余字符串,不够k个,则按照下面的全部进行反转
i + k
不进行反转的情况只有一种,那就是剩余字符串的长度不够k个,if (i + k > s.size())
所以要全部进行反转
LeetCode测试
这个题的代码虽然简短,但是感觉理解起来并不简单
点击查看代码
class Solution {
public:
string reverseStr(string s, int k) {
for (int i = 0; i < s.size(); i += 2 * k) {
if (i + k <= s.size()) reverse(s.begin() + i, s.begin() + i + k);
if (i + k > s.size()) reverse(s.begin() + i, s.end());
}
return s;
}
};
替换数字
题目描述:卡玛网替换数字
文档讲解:代码随想录(programmercarl)541. 反转字符串II
这属于一道扩充字符串的题目,关键仍然在双指针
梳理
-
首先查询字符串中的数字个数
-
对字符串的长度进行扩充,注意这个代码是
s.resize(s.size() + count * 5)
,这里要乘5不要忘记 -
定义一个
left
指针指向替换之前的字符串,一个right
指针指向替换之后的字符串。而遍历的终止条件就是left
指针把原先的字符串遍历完 -
循环遍历字符串,注意循环的终止条件是
left >= 0
,这里为什么不是left > 0
呢?其实这里可以举个极端的例子,例如字符串为"1"
,但是仍然要进行一次循环,将"1"
变为"number"
,但是left = 1 - 1
之后初始为0,写成left > 0
就直接结束了,所以不能这么写
卡玛网测试
代码不太好写,里面好多小细节感觉
点击查看代码
# include<iostream>
using namespace std;
int main() {
string s, result;
cin >> s;
int count = 0, oldSize;
oldSize = s.size();
for (int i = 0; i < s.size(); i++) {
if (s[i] <= '9' && s[i] >= '0') count++;
}
s.resize(s.size() + count * 5);
int left, right;
for (left = oldSize - 1, right = s.size() - 1; left >= 0;) {
if (s[left] <= '9' && s[left] >= '0') {
s[right--] = 'r';
s[right--] = 'e';
s[right--] = 'b';
s[right--] = 'm';
s[right--] = 'u';
s[right--] = 'n';
left--;
}
// 如果不是数字
else {
s[right--] = s[left--];}
}
cout << s << endl;
}
151.翻转字符串里的单词
题目描述:力扣151
文档讲解:代码随想录(programmercarl)151.翻转字符串里的单词
视频讲解:《代码随想录》算法视频公开课:字符串复杂操作拿捏了! | LeetCode:151.翻转字符串里的单词
代码随想录视频内容简记
核心内容是去除空格,仍旧使用的是双指针法
梳理
-
首先去除字符串里所有的空格
-
对字符串大小进行更新
-
将所有的字符进行反转
-
对每个单词进行反转
大致代码内容
- 去除空格。首先想到的是如果fast指针指向的内容不为空,则赋值给slow指针。同时,因为第一个单词之前是没有空格的,其余的单词之间都是有空格的。所以如果slow指针指向的不是第一个单词,
if (slow != 0) s[slow++] = ' '
。为了让每个单词之间有' '
进行连接,slow发生变化之后,一定是一次性指向一个完整的单词并发生移动,那么,就必然要使用while
来让fast指针为slow指针进行完整的赋值。
注意这里的条件判断,必须得带上fast < s.size()
,因为假如fast
走到最后一个单词,后面没有空格了,这个while
就没有出口了
for (int fast = 0; fast < s.size(); fast++) {
if (s[fast] != ' ') {
if (slow != 0) s[slow++] = ' ';
while (fast < s.size() && s[fast] != ' ') {
s[slow++] = s[fast++];
}
}
}
这个注意,刚开始的时候循环条件写的i,后面循环体用的fast,没看出来,结果一直报错,不要写错了。
-
s.resize(slow);
-
reverse(s.begin(), s.end())
对所有的字符进行反转,这个注意,如果是直接用的库函数reverse()的话,有两个参数,一个是s的起始,一个是s的终止。 -
对单词进行翻转,
for (int i = 0; i <= s.size(); i++)
,注意k哥说过,reverse()库函数进行反转是一个左闭右开区间的,所以我们对最后一个单词进行反转的时候,他的if判断条件必须等于s.size()
,所以我们在循环的时候就不能只写i < s.size()
了
LeetCode测试
感觉不好写这个题
点击查看代码
class Solution {
public:
string reverseWords(string s) {
int fast = 0, slow = 0;
for (int fast = 0; fast < s.size(); fast++) {
if (s[fast] != ' ') {
if (slow != 0) s[slow++] = ' ';
while (fast < s.size() && s[fast] != ' ') {
s[slow++] = s[fast++];
}
}
}
s.resize(slow);
reverse(s.begin(), s.end());
int start = 0;
for (int i = 0; i <= s.size(); i++) {
if (s[i] == ' ' || i == s.size()) {
reverse(s.begin() + start, s.begin() + i);
start = i + 1;
}
}
return s;
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端