day08字符串的操作
LeetCode:344.反转字符串
链接:https://leetcode.cn/problems/reverse-string/
问题描述
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s
的形式给出。
不要给另外的数组分配额外的空间,你必须**原地修改输入数组**、使用 O(1) 的额外空间解决这一问题。
代码实现
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]);
}
}
};
注意点
- 此处非直接调用reverse函数解决问题。调用不相干的简单库函数没问题
LeetCode:541. 反转字符串II
链接:https://leetcode.cn/problems/reverse-string-ii/
问题描述
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
代码实现
class Solution {
public:
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.begin() + i,s.begin() + i + k);
}else{
//剩余的小于k个,全部反转
reverse(s.begin() + i,s.end());
}
}
return s;
}
};
注意点
- 前面的if实现的是对于s进行分组,前面的 2k个元素全部进行了前n个反转,反转通过reverse实现,问题的关键在于分组
剑指 Offer 05. 替换空格
链接:https://leetcode.cn/problems/ti-huan-kong-ge-lcof/
问题描述
请实现一个函数,把字符串 s
中的每个空格替换成"%20"。
代码实现
class Solution {
public:
string replaceSpace(string s) {
int count = 0;//记录空格的数量
int sOldSize = s.size();
for(int i = 0;i < s.size();i++){
if(s[i] == ' '){
count++;
}
}
//空格占1个改成%20变成三个,size大小进行改变
s.resize(s.size() + count * 2);
int sNewSize = s.size();
//选择从后向前把所有的空格全替换成%20
//如果从前向后替换,后面的index需要重新找
//i是新指针一定落后于j这个j
for(int i = sNewSize - 1,j = sOldSize - 1;j < i;i--,j--){
//不是' '定位过去同步起来
if(s[j] != ' '){
s[i] = s[j];
}else{
s[i] = '0';
s[i - 1] = '2';
s[i - 2] = '%';
i = i - 2;
}
}
return s;
}
};
注意点
- 双指针法解决问题,注意方法是从后向前去遍历,遇到空格将空格替换成 %20
- 不是空格,用快指针把位置传递给慢指针,如果是空格,调用慢指针去换
LeetCode:151.翻转字符串里的单词
链接:https://leetcode.cn/problems/reverse-words-in-a-string/
问题描述:
给你一个字符串 s ,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
代码实现:
class Solution {
public:
string reverseWords(string s) {
//程序的步骤是先全部反转,然后再进去删掉中间多余的空格,再去删掉前面的空格,最后把字符串中除了空格外的再翻转
removeExtraSpaces(s);
reverse(s, 0, s.size() - 1);
//接下来反转每一个单词
int start = 0;
for(int i = 0;i <= s.size();++i){
if(i == s.size() || s[i] == ' '){//空格或者尾部,就是一个单词结束
reverse(s,start, i - 1);
start = i + 1;
}
}
return s;
}
//翻转全部字符串的写法
void reverse(string& s,int start,int end){
for(int i = start,j = end;i < j;i++,j--){
swap(s[i],s[j]);
}
}
//相邻单词中多个空格只保留其中的一个
//采用的是快慢指针的思想
void removeExtraSpaces(string& s){
int slow = 0;
for(int fast = 0;fast < s.size();fast++){
if(s[fast] != ' '){
//slow指针给每个单词前面赋一个' ';
//slow不是第一个元素的时候
if(slow != 0) s[slow++] = ' ';
//如果快指针指向的单词不是空的,把快指针的单词赋给慢指针
//遍历下去,快指针找到一个单词,就赋值给满指针
while(fast < s.size() && s[fast] != ' '){
s[slow++] = s[fast++];
}
}
}
s.resize(slow);
//重新构造的是slow数组,其中的去除了多余的空格
//去除后的为第一个单词,最后一个单词,中间全部是一个空格
}
};
注意点
- 全是
题目:剑指Offer58-II.左旋转字符串
链接: https://leetcode.cn/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/
问题描述
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
代码实现
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;
}
};
注意点
- 分成三块
- 第一部分前n个反转
- 第二部分n+1到尾部的反转
- 第三部分整体反转