344. 反转字符串
题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
视频讲解:字符串基础操作! | LeetCode:344.反转字符串_哔哩哔哩_bilibili
文章讲解:代码随想录
class Solution {
public:
void reverseString(vector<char>& s) {
int left = 0;
int right = s.size()-1;
while(left<right){
char tmp = s[left];
s[left] = s[right];
s[right] = tmp;
left++;
right--;
}
}
};
- 时间复杂度: O(n)
- 空间复杂度: O(1)
可以直接用swap交换
541. 反转字符串II
题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
视频讲解:字符串操作进阶! | LeetCode:541. 反转字符串II_哔哩哔哩_bilibili
文章讲解:代码随想录
class Solution {
public:
string reverseStr(string s, int k) {
int left, right;
int count = s.size()/(k*2);
for(int c = count; c>0; c--){
left = (c-1)*(k*2);
right = left+k-1;
while(left<right){
swap(s[left],s[right]);
left++;
right--;
}
}
int rest = s.size()%(k*2);
left = count*(k*2);
if(rest<k){
right = s.size()-1;
}
else{
right = left+k-1;
}
while(left<right){
swap(s[left],s[right]);
left++;
right--;
}
return s;
}
};
- 时间复杂度: O(n)
- 空间复杂度: O(1)
剑指Offer 05.替换空格
题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
【无视频讲解】
文章链接:代码随想录
【思路】
首先扩充数组到每个空格替换成"%20"之后的大小。
然后从后向前替换空格,也就是双指针法,过程如下:
i指向新长度的末尾,j指向旧长度的末尾
class Solution {
public:
string replaceSpace(string s) {
int count = 0; // 统计空格的个数
int sOldSize = s.size();
for(int i=0; i<sOldSize; i++){
if(s[i]==' '){
count++;
}
}
// 扩充字符串s的大小,也就是每个空格替换成"%20"之后的大小
s.resize(s.size()+count*2); // %20有三个字符,比空格多了两个字符
int sNewSize = s.size();
// 从后向前将空格替换为"%20"
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 -= 2;
}
}
return s;
}
};
- 时间复杂度:O(n)
- 空间复杂度:O(1)
151. 翻转字符串里的单词
题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
视频讲解:字符串复杂操作拿捏了! | LeetCode:151.翻转字符串里的单词_哔哩哔哩_bilibili
文章讲解:代码随想录
【解题思路】
- 移除多余空格
- 将整个字符串反转
- 将每个单词反转
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 reverseWords(string s) {
int 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];
slow++;
fast++;
}
}
}
s.resize(slow);
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; //更新下一个单词的开始下标start
}
}
return s;
}
};
- 时间复杂度: O(n)
- 空间复杂度: O(1)
剑指Offer58-II.左旋转字符串
题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
【无视频讲解】
文章链接:代码随想录
为了让本题更有意义,提升一下本题难度:不能申请额外空间,只能在本串上操作。
这道题目依然可以通过局部反转+整体反转 达到左旋转的目的。
具体步骤为:
- 反转区间为前n的子串
- 反转区间为n到末尾的子串
- 反转整个字符串
最后就可以达到左旋n的目的,而不用定义新的字符串,完全在本串上操作。
class Solution {
public:
string reverse(string s, int begin, int end){
while(begin<end){
swap(s[begin++], s[end--]);
}
return s;
}
string reverseLeftWords(string s, int n) {
// 反转前n个字符
s = reverse(s, 0, n-1);
// 反转剩余的字符
s = reverse(s, n, s.size()-1);
// 反转字符串
s = reverse(s, 0, s.size()-1);
return s;
}
};
- 时间复杂度:O(n)
- 空间复杂度:O(1)