代码随想录训练营day07(字符串)
344.反转字符串
题目
库函数reverse的底层实现
思考历程
和反转链表有什么区别?
区别于反转链表:字符串可以看作是字符的数组,反转数组可以直接交换值,链表是逐一修改指向。
解题方法(双指针向中间靠拢)
- 流程:
1、字符串vector也是数组
2、用双指针从左端、右端开始,互相交换
3、然后向中间移动 - 图解
难点
- 犯错:字符串最后一个字符不应该是 j = s.size(),而是 j = s.size()-1
- 新知识点:for循环多个参数
代码
class Solution {
public:
void reverseString(vector<char>& s) {
for(int i = 0, j = s.size()-1;i<j;i++,j--){
swap(s[i],s[j]);
}
}
};
541. 反转字符串II(难)
题目
思考历程
看不懂题目的规则
题意:每2k个字符,反转它的前k个字符;如果不够k个,就全部反转。
解题方法(简化为只有两种情况)
- 流程:
1、i 每次以2k的长度去遍历
2、只要i及其后面还有k个字符,就可以反转前k个字符
3、剩余情况,就把剩余字符全部反转 - 图解
难点
- 巧妙:把需要反转前k个字符的两种情况合并了、i每次+2k
- 找不准边界条件:从i数起前k个字符:[i, i+k-1],i+k==s.size()是符合“剩余字符有k个”的边界
- continue的用法:提前结束本轮遍历,进入下一轮遍历
代码
class Solution {
public:
string reverseStr(string s, int k) {
for(int i=0; i<s.size();i=i+2*k){
if(i+k<=s.size()){//取等号的时候,刚好还剩[i,i+k-1]这k个字符
reverse(s.begin()+i,s.begin()+i+k);//reverse是左闭右开
continue;
}
else{
reverse(s.begin()+i,s.end());
}
}
return s;
}
};
剑指Offer 05.替换空格
题目
解题方法(双指针,新数组根据旧数组赋值)
- 流程:
1、先统计空格数目,然后扩充成新的数组
2、从旧数组右端和新数组右端开始遍历,旧数组元素是空格就替换,旧数组元素不是空格就原样复制 - 图解
难点
- 难点:为什么从后向前进行操作,
- 好处1:不用申请新数组。
- 好处2:避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
- 难点:为什么i从旧数组的末尾开始
因为新数组是从后往前填充的,所以需要从旧数组末尾开始移动,去判断新数组该填什么值。(旧数组是新数组的依据)
代码
class Solution {
public:
string replaceSpace(string s) {
int count = 0;
int oldSize = s.size();
for(int i = 0; i<oldSize; i++){//统计空格的数量
if(s[i] == ' '){
count++;
}
}
int newSize = oldSize + count*2;//%20比空格多两个字符
s.resize(newSize);//新数组
for(int i = oldSize-1,j = newSize-1;i<j;i--,j--){
if(s[i]==' '){
s[j] = '0';
s[j-1] = '2';
s[j-2] = '%';
j = j-2;
}
else{
s[j] = s[i];
}
}
return s;
}
};
151.翻转字符串里的单词(难)
题目
待填坑
思考历程
解题方法
难点
代码
在这里插入代码片
剑指Offer58-II.左旋转字符串
题目
思考历程
想不到
解题方法(反转再反转再反转)
先反转前k位,再反转剩余部分,最后反转整个字符串
- 图解
难点
- 难点:想不到这种解法
- 对string不熟悉
1、可以通过[]方式取字符,与数组用法一致
2、与数组的区别:可以理解为是一个字符数组
3、string、char*、vector的区别
- string:C++ 标准库中的string类,提供了高级的字符串处理方式,是一个对象。
- char*:C风格的字符串,是一个指向字符的指针,指向字符串的起始位置。
- vector:C++ 标准库中的vector类,用于表示一组字符,是一个对象,不如string专业
- reverse算法的使用:reverse(开始迭代器,结束迭代器)
代码
class Solution {
public:
string reverseLeftWords(string s, int n) {
reverse(s.begin(),s.begin()+n);
reverse(s.begin()+n,s.end());
reverse(s.begin(),s.end());
return s;
}
};