💫坚持真的很难,希望自己不要松懈啊。
📆学习日期:2025年2月7日23:03:23
💻学习内容:反转字符串 | 代码随想录 反转字符串II | 代码随想录
⏲️学习时长:1h25min
练习题目1-反转字符串
题目描述
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s
的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例 1:
输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]
示例 2:
输入:s = ["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]
提示:
1 <= s.length <= 105
s[i]
都是 ASCII 码表中的可打印字符
解题思路
- 整体思路&&注意事项
- 字符串和数组的算法思路基本差不多
- 本题为 双指针法 的经典应用
- 代码实现
- 使用两个指针进行头尾元素的交换
- 指针
i
指向头部,指针j
指向尾部,两个元素交换,指针逐步向中间移动 - 边界条件:“代入法”
例如奇数 s = ["h","e","l","l","o"],len=5, i<len/2,即i=0,1 其中2不需要交换,偶数 s = ["h","e","l","l"] i<len/2,即i=0,1,两个交换也成立,因此条件为 i<len/2(而不是i<=len/2)
for(i=0,j=len-1;i<len/2;i++,j--)
j
的边界条件不需要,因为i
j
是同时移动的
- 使用
swap()
函数进行元素交换
- 什么时候可以使用库函数:库函数直接解决题目,则不要使用,库函数是实现的一部分,可以使用。
Bug
无
class Solution {
public:
void reverseString(vector<char>& s) {
int len=s.size();//字符串长度
for(int i=0,j=len-1;i<len/2;i++,j--){
char temp=s[i];//交换 //使用库函数 swap(s[i],s[j]),是同款操作
s[i]=s[j];
s[j]=temp;
}
}
};
练习题目2-反转字符串II
题目描述
设置标签 541. 反转字符串 II - 力扣(LeetCode)
给定一个字符串 s
和一个整数 k
,从字符串开头算起,每计数至 2k
个字符,就反转这 2k
字符中的前 k
个字符。
- 如果剩余字符少于
k
个,则将剩余字符全部反转。 - 如果剩余字符小于
2k
但大于或等于k
个,则反转前k
个字符,其余字符保持原样。
示例 1:
输入:s = "abcdefg", k = 2
输出:"bacdfeg"
示例 2:
输入:s = "abcd", k = 2
输出:"bacd"
提示:
1 <= s.length <= 104
s
仅由小写英文组成1 <= k <= 104
解题思路
- 整体思路&&注意事项
- 模拟此复杂规则之下的反转,没有其他的算法
- 与 反转字符串 是一脉相承的,使用到了 反转字符串 的操作
- 遍历字符串的for循环不一定写
i++
, 以2k
为一个操作单位进行遍历,i+=2k
- 代码实现
for(i=0;i<s.size();i+=2k)
//对字符串要进行一段一段的操作- 需要操作的是前
k
个字符
if(i+k<=s.size());
需要凑够k
个可以操作的数//注意边界条件
reverse(s,i,i+k);//这里使用了库函数,可以借鉴上一题反转字符串的操作
- 尾部不足
k
个字符的操作:
将剩余的字符全部反转 reverse(s,i,s.size());
Bug
reverse(s,i,s.size());
这个是伪代码的形式,真实的reverse函数不是这样的
class Solution {
public:
//自定义my_reverse函数
//void() my_reverse()
string reverseStr(string s, int k) {
for(int i=0;i<s.size();i+=2*k){//i以2k为单位遍历字符串,相当于计数了
if(i+k<=s.size()){//以2k为单位跳,最后这段需要凑够k个
reverse(s.begin()+i,s.begin()+i+k);
//continue;//进入下一个2k,没搞懂这个continue,用if-else也可以
}
//尾部没凑够k个
else reverse(s.begin()+i,s.end());
}
return s;
}
};
class Solution {
public:
void reverse(string& s, int start, int end) {
for (int i = start, j = end; i < j; i++, j--) {
swap(s[i], s[j]);
}
}
string reverseStr(string s, int k) {
for (int i = 0; i < s.size(); i += (2 * k)) {
// 1. 每隔 2k 个字符的前 k 个字符进行反转
// 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
if (i + k <= s.size()) {
reverse(s, i, i + k - 1);
continue;
}
// 3. 剩余字符少于 k 个,则将剩余字符全部反转。
reverse(s, i, s.size() - 1);
}
return s;
}
};
class Solution {
public:
string reverseStr(string s, int k) {
int n = s.size(),pos = 0;
while(pos < n){
//剩余字符串大于等于k的情况
if(pos + k < n) reverse(s.begin() + pos, s.begin() + pos + k);
//剩余字符串不足k的情况
else reverse(s.begin() + pos,s.end());
pos += 2 * k;
}
return s;
}
};
学习总结
- 双指针的思路 待总结
代码随想录-反转链表
swap()
函数 待总结- 分段处理的
for
循环操作,i
的跳数
相关题目
反转字符串中的元音字母 简单
反转字符串 II 简单
反转字符串 简单
故障键盘 简单